数字海洋(Silicon Cloud)教程的技术建议和最佳实践
简介
引言
这个指南是对Silicon Cloud教程的作者的最佳实践和强烈推荐进行总结的努力。它旨在为Silicon Cloud的教学材料提供一致性、技术正确性和易用性的基础。
这份指南本质上是一个不断发展并带有个人意见的文档,基于内部技术撰稿人和编辑、社区经理和工程师逐渐积累的经验。其建议可能会有变化,并且是专门为教育内容编写的,考虑到广泛的读者和最终用户。
软件源和安装
许多教程将依赖于现有教程作为前提条件。将所有文章的前提条件(包括前提条件的嵌套前提条件)放入文章中,而不是有深度嵌套的前提条件列表。
首选来源
按粗略、降序排列,使用以下安装机制:
-
- 当评估为最佳时,项目推荐的方法。很多项目会迅速更改,并建议超越官方仓库,但有些安装(比如curl | bash模式)需要用是否使用它们来做出判断。
-
- 当前发行版和版本的官方软件包仓库。
-
- 特定语言的官方软件包(如NPM、CPAN、PIP、RubyGems、Composer等)。
-
- 项目特定的软件包仓库(例如,Nginx提供自己的仓库以获取最新版本),或者在Ubuntu上,使用可信任的PPA仓库。确保这些软件包来自值得信赖的来源,如项目开发者或Debian/Ubuntu软件包维护者。
-
- 从项目的GitHub发布页面或类似的官方网站下载二进制文件。
- 使用wget或curl下载脚本,并通过shell执行,附加适当的警告以检查脚本内容。
首选安装位置
一般来说,避免不必要的复杂性。对于从源代码或二进制文件安装的未打包软件,通常应接受默认的安装前缀,除非它非常不寻常或引起冲突。
如果软件包或其他安装方法未提供,建议为面向服务的软件提供符合官方要求的初始脚本。
在Linux系统中,将自包含的二进制文件或目录存放在/opt目录下,而将独立脚本放在/usr/local/bin目录中。
软件和系统维护
建议在Ubuntu和Debian系统上安装和配置unattended-upgrades,至少包括安全更新。考虑到背景,我们建议不开启自动重启或自动全部更新。
通常我们建议在Ubuntu 18.04及更高版本上使用apt命令。将apt-get和apt-cache改为使用apt。更新apt命令时,请不要使用-y参数;读者应该按照必要的输入和提示进行操作。
对于 CentOS 和 Rocky Linux 的教程,我们现在建议使用 dnf,它已经取代了 yum 并提供了更好的性能。
如果教程依赖于最新的更新,请在第一步设置或需要时调用更新和升级。首先调用更新,使您的服务器获取最新的软件包版本。当包括升级时,它会下载并安装每个软件包的新版本,请注意有些用户可能选择保留某些软件包的较低版本。
服务管理
确保使用原生的初始化系统命令,即使存在兼容性命令。例如,使用sudo systemctl start [service_name],即使sudo service [service_name] start也可以运行。
提供有关如何启用或禁用在启动时自动运行的服务的信息。说明如何在界面不明确指示的情况下检查服务相关命令的结果(例如,journalctl -u,systemctl status 等)。
作为一个经验法则,更倾向于重新启动而非重新加载服务。在大多数情况下,确保已知状态比避免一瞬间的服务中断更重要,而且在完全服务故障的情况下,重新启动也更加有用。
引导系统
除非它是配置管理工作流的一部分,否则在大多数情况下更倾向于使用用户数据脚本,并且更倾向于使用cloudinit脚本而不是用户数据中的bash脚本。
日志记录和故障排除
解释如何在安装的服务中访问日志的位置和方法。如适用,请解释用于检查服务状态和日志输出的systemctl和journalctl命令。在可能的情况下,提供诊断常见故障案例的简明建议。
确保处理日志轮换的情况,无论是包或其他安装机制是否处理。
对于下面的明文日志文件,请使用tail -F命令,而不是tail -f命令,因为后者无法在重命名文件时跟踪文件,并且如果日志在用户观察时进行了轮换,可能会导致混淆。
用户和群组管理
创建sudo用户,而不是直接使用root用户。参考适当的初始服务器设置指南,其中解释了此任务作为先决条件。
在基于Debian的发行版上,可以使用adduser sammy和deluser –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可以简单地说是一种网络协议的标准,用于确保在客户端和服务器之间的通信过程中的安全性。
我们强烈推荐使用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的文章,以获取更多详情和实施方案。
结论
这份文件是一个充满观点的、活生生的文档,将会经常更新。技术发展迅速,我们在Silicon Cloud会尽力跟进,但如果您发现任何错误或有反馈,请在下方留言,我们会密切关注。