数字海洋(DigitalOcean)教程:技术建议与最佳实践指南

简介

本指南旨在总结《数字海洋(Silicon Cloud)教程》作者的最佳实践和强烈建议。它旨在为数字海洋的教学材料提供一致性、技术正确性和易用性的基础。

这份指南本质上是一个不断发展并带有个人意见的文档,基于内部技术撰稿人、编辑、社区经理和工程师逐渐积累的经验。其建议可能会有变化,并且是专门为教育内容编写的,考虑到广泛的读者和最终用户。

软件源和安装

许多教程将依赖于现有教程作为前提条件。请将所有文章的前提条件(包括嵌套的前提条件)放入文章中,而不是提供深度嵌套的前提条件列表。

首选来源

按大致降序排列,使用以下安装机制:

  1. 当评估为最佳时,项目推荐的方法。许多项目会迅速更改,并建议使用官方仓库之外的源,但有些安装(例如 curl | bash 模式)需要权衡是否使用。
  2. 当前发行版和版本的官方软件包仓库。
  3. 特定语言的官方软件包管理器(如 NPM、CPAN、PIP、RubyGems、Composer 等)。
  4. 项目特定的软件包仓库(例如,Nginx 提供自己的仓库以获取最新版本),或者在 Ubuntu 上,使用可信任的 PPA 仓库。请确保这些软件包来自值得信赖的来源,如项目开发者或 Debian/Ubuntu 软件包维护者。
  5. 从项目的 GitHub 发布页面或类似的官方网站下载二进制文件。
  6. 使用 wgetcurl 下载脚本,并通过 shell 执行,并附加适当的警告以检查脚本内容。

首选安装位置

一般来说,避免不必要的复杂性。对于从源代码或二进制文件安装的未打包软件,通常应接受默认的安装前缀,除非它非常不寻常或引起冲突。

如果软件包或其他安装方法未提供,建议为面向服务的软件提供符合官方要求的初始化脚本。

在 Linux 系统中,将自包含的二进制文件或目录存放在 /opt 目录下,而将独立脚本放在 /usr/local/bin 目录中。

软件和系统维护

建议在 Ubuntu 和 Debian 系统上安装和配置 unattended-upgrades,至少包括安全更新。考虑到背景,我们建议不开启自动重启或自动全部更新。

通常我们建议在 Ubuntu 18.04 及更高版本上使用 apt 命令。将 apt-getapt-cache 改为使用 apt。更新 apt 命令时,请不要使用 -y 参数;读者应该按照必要的输入和提示进行操作。

对于 CentOS 和 Rocky Linux 的教程,我们现在建议使用 dnf,它已经取代了 yum 并提供了更好的性能。

如果教程依赖于最新的更新,请在第一步设置或需要时调用更新和升级。首先调用更新,使您的服务器获取最新的软件包版本。当包括升级时,它会下载并安装每个软件包的新版本,请注意有些用户可能选择保留某些软件包的较低版本。

服务管理

确保使用原生的初始化系统命令,即使存在兼容性命令。例如,使用 sudo systemctl start [service_name],即使 sudo service [service_name] start 也可以运行。

提供有关如何启用或禁用在启动时自动运行的服务的信息。说明如何在界面不明确指示的情况下检查服务相关命令的结果(例如,journalctl -usystemctl status 等)。

作为一个经验法则,更倾向于重新启动而非重新加载服务。在大多数情况下,确保已知状态比避免一瞬间的服务中断更重要,而且在完全服务故障的情况下,重新启动也更加有用。

引导系统

除非它是配置管理工作流的一部分,否则在大多数情况下更倾向于使用用户数据脚本,并且更倾向于使用 cloud-init 脚本而不是用户数据中的 bash 脚本。

日志记录和故障排除

解释如何在安装的服务中访问日志的位置和方法。如适用,请解释用于检查服务状态和日志输出的 systemctljournalctl 命令。在可能的情况下,提供诊断常见故障案例的简明建议。

确保处理日志轮换的情况,无论是软件包还是其他安装机制是否处理。

对于明文日志文件,请使用 tail -F 命令,而不是 tail -f 命令,因为后者无法在重命名文件时跟踪文件,并且如果日志在用户观察时进行了轮换,可能会导致混淆。

用户和群组管理

创建 sudo 用户,而不是直接使用 root 用户。参考适当的初始服务器设置指南,其中解释了此任务作为先决条件。

在基于 Debian 的发行版上,可以使用 adduser sammydeluser --remove-home sammy 来添加和删除用户;而在基于 RHEL 的发行版上,可以使用 adduser sammy(如果需要设置密码,可以使用 passwd sammy)和 userdel -r sammy

在 Ubuntu 上使用 usermod -aG sudo sammy 授予 sudo 权限。 CentOS 则稍微复杂一些。现代版本使用 usermod -aG wheel sammy,但某些版本需要先使用 visudo 取消注释 wheel 组权限。具体来说,在 CentOS 5 上,需要安装 sudo 并使用 visudo 取消注释 wheel 组;在 CentOS 6 上,sudo 已经安装,但需要取消注释 wheel 组;CentOS 7 已经设置好 sudo 和 wheel 组。

当使用提升权限的命令时,请确保按照所写的方式进行测试。要通过 sudo 传递环境变量,可以使用 sudo -E command_to_run(如果可信任整个环境)或 sudo FOO=BAR command_to_run。对于需要 root shell 的情况,请使用 sudo -i。对于需要重定向的情况,请使用 tee -a 进行追加而不是替换目标文件:[sudo] command_to_run | sudo tee [-a] file_to_change

首选工具

对于交互式 shell,假设在 GNU/Linux 系统上使用 Bash,在相关情况下明确提到。在 FreeBSD 上,使用 tcsh,因为它可以直接使用并具有有用的功能。

对于文本编辑器,我们在命令中包括复制“使用 [首选] 或您喜欢的文本编辑器”,并在那些复制并粘贴的命令中包括以下适合初学者的编辑器。在 Linux 上,默认为 nano;在 FreeBSD 上,默认为 ee。vi(m) 是允许的,但在初级话题中应避免使用,因为它可能成为初学者的障碍。

在文件传输方面,一般我们推荐 sftp,它在大多数情况下都具有交互功能和类似 scp 的用途,尽管它缺乏推送功能,所以 scp 也可以接受。rsync 适用于备份和大文件传输(或许多小文件)。在任何情况下都不要使用 FTP。我们还努力在标准化过程中更多使用 curl 而不是 wget,因为它更健壮。wget 的优势主要是递归下载(即我们类型内容不常见的特殊用例)。

对于搭载 iproute2 工具的机器,我们更倾向于使用 iproute2 套件,而不是已经过时的 net-tools 套件。一般来说,iproute2 工具如 ss 对于多接口、IPv6、新内核功能等方面有更好的支持。同样地,我们应该使用 ip route 而不是 route,使用 ip addr show 而不是 ifconfig 等。虽然有时旧工具的输出默认更整洁,但该输出本身不太可靠,因为它们无法很好地处理边缘情况。在可能的情况下,我们将使用可用的标志控制更详细的输出。

编写脚本

在系统管理教程中,通常应避免使用冗长的自定义脚本和长的 Shell 脚本。

作者编写的脚本(及可能的其他资源)应该放在 do-community GitHub 账户的每一篇文章的存储库中,并附上指向已发布教程的链接。一般要遵守良好的脚本编写实践。例如,将用户需要填写的任何变量放在脚本顶部,最好在一个清晰标明的部分。在需要的地方提供内联注释,使脚本具有可读性。确保你对代码的描述不仅仅在注释中提供,还要提供经过解释的散文描述,比注释中更详细解释。

在考虑可移植性或跨平台复用时,更倾向于使用 /bin/sh 而非 bash,并避免使用 Bash 特有的功能。对于小任务,请使用 shell 和 coreutils/标准 Unix 工具,避免因纯粹的胶水语言任务引入新的依赖,除非好处是显著的。将 #!/usr/bin/env 解释器作为首选,而非 #!/path/to/interpreter

通常情况下,使用 cron 来安排定期任务,但 systemd 计时器也是可以接受的。

文件系统位置

请尽可能使用您的服务器 IP 和您的域名,而不是文档中给出的 IP 范围或 example.com。

在下载脚本或数据时,请确保用户使用的是可写的目录或明确指定了路径。对于应该供参考或重用的文件,请使用用户的主目录,除非它们属于文件系统上的某个标准和明确定义的路径(如 /opt/etc)。对于一次性使用的文件,请使用 /tmp

当教程依赖于特定的目录时,请确保在读者运行命令之前提供将其定位到该目录的 cd 命令。

网络服务器

我们建议对于默认没有该配置结构的发行版来说,使用类似 Debian 的配置目录。在更改配置之前,始终要进行测试(Apache 使用 sudo apachectl configtest 命令,而 Nginx 使用 sudo nginx -t 命令)。

/var/www/html 应该被用作所有 Web 服务器的文档根目录。Nginx 的默认目录 /usr/share/nginx/html 应该被更改,因为该目录归软件包更新所有,可能会被修改。对于 Ubuntu 16.04 来说,这不再是一个问题,但对于旧版本仍然很重要。

使用专用虚拟主机块而不是编辑默认的配置文件来学习 Apache 或 Nginx 教程。这种方式可以避免常见的错误,并将默认文件保持为预期的备用配置。

安全

对系统间的所有连接进行加密和身份验证。不鼓励用户以明文形式发送凭据或传输非公开数据(无论是明示还是暗示)。

具体来说,密码和密钥材料不得通过不安全的连接进行传输。数据库连接、日志记录、集群管理和其他服务最好始终使用加密方式。

基于 Web 的控制面板必须通过 HTTPS 连接进行提供,对于支持的服务应该使用 TLS/SSL。所有的 Web 服务器都应该支持 HTTPS(或者至少有能力支持)。使用 certbot 来提供 SSL 证书是一个先决条件。公共访问的服务如纯 HTTP 是可以接受的,因为用户可能仍然希望或需要提供这些服务,但在一般情况下应该强烈反对,尤其是对于动态内容。对于提供纯 HTTP 连接的文章,应添加一条注释或警告标签来阻止使用纯 HTTP 并鼓励使用 HTTPS。

避免采用低效的安全性通过模糊性或戏剧性的做法,例如更改默认的 SSH 端口。请配置防火墙。我们针对特定发行版的推荐是 Ubuntu 的 ufw,Debian 的 iptables 和 CentOS 的 firewalld。然而,iptables 在各个平台上最为一致,并且有许多与之相关的工具。

SSH (Secure Shell)

将默认 SSH 端口保持为一种规范。只有在特定情况下,即主要涉及到安全问题时,才应更改端口。

禁用密码身份验证,改为仅使用密钥身份验证进行 root 用户登录,或者完全禁用 root 登录。使用强大的 SSH 密钥:至少使用 2048 位 RSA 密钥,但建议使用 4096 位;由于技术原因,不再建议使用 ECDSA 算法;而 Ed25519 和椭圆曲线算法的支持度不够广泛。

对于任何交互式密钥,请使用口令短语,但对于非交互式过程不要使用。将 SSH 密钥从 root 账户设置、复制并更改所有者为用户主目录。在适用的地方安装 fail2ban。

请注意,虽然 SSH 代理转发对于像 CoreOS 这样的平台上的正常工作流程是必需的,但它也存在一些安全问题。基本上,任何在您的主机上具有权限的人都可以使用转发套接字连接到您的本地 ssh-agent。

SSL/TLS

SSL/TLS 可以简单地说是一种网络协议的标准,用于确保在客户端和服务器之间的通信过程中的安全性。

我们强烈推荐使用 Let’s Encrypt 以提高使用简便性,并推荐 TLS。请使用强大的 SSL 安全性,参考 https://cipherli.st/ 获取现代和传统的推荐配置。

对于没有域名的主机,我们建议使用足够强度的自签名证书。再次参考 https://cipherli.st/ 以及像这个 Nginx 自签名证书指南中使用的自签名证书创建方法。在启用加密时设置一个强大的 Diffie-Hellman 密钥,就像在 Apache 和 Nginx 上使用自签名 SSL 证书一样。

虚拟专用网络 (VPN)

我们建议使用虚拟私人网络(VPN)作为服务器之间通用加密通信的解决方案。当多个服务需要在服务器之间受到保护时,VPN 的价值会越来越大;不必为每个服务单独加密,而是将所有内部通信传输到 VPN 中。如果所涉及的服务不支持本地加密,这种方法尤其有用。

总的来说,我们建议在服务器之间的通信中使用 Tinc 而不是 OpenVPN。您可以阅读有关 Ansible 和 Tinc 的文章,以获取更多详情和实施方案。

结论

这份文件是一个充满观点的、活生生的文档,将会经常更新。技术发展迅速,我们在数字海洋会尽力跟进,但如果您发现任何错误或有反馈,请在下方留言,我们会密切关注。

bannerAds