如何使用Cloud-Config进行初始服务器设置

来自菜鸟教程
跳转至:导航、​搜索

介绍

随着 DigitalOcean 元数据服务 的引入,您甚至可以在登录之前开始配置您的服务器。 简而言之,元数据服务是您的服务器在启动过程中可以访问的 HTTP 位置。

元数据位置将包含有关服务器配置和环境的基本数据,例如网络地址、主机名等。 在初始设置期间,可以通过名为 cloud-init 的程序下拉这些值,以帮助配置基本服务。

最强大的功能是您可以在使用名为 user-data 的字段创建服务器时将脚本传递给元数据服务。 这将在初始引导过程中运行,并且非常灵活,允许您完成您可以编写的任何脚本。

要传入的最常见的脚本类型称为 cloud-config 脚本。 这是一个 YAML 格式的文件,它提供了简单易读的方法来通过声明设置通用配置项。 它还能够为其他任务运行任意命令。

在本指南中,我们将通过一个简单的示例来熟悉 DigitalOcean 元数据服务和 cloud-config 文件。 我们将重新创建 Ubuntu 14.04 初始服务器设置指南中概述的一些步骤,以进行演示。

目标

为了成功复制 Ubuntu 14.04 初始服务器设置指南 中的步骤,我们的脚本必须执行许多任务。

这些是上述指南完成的基本任务:

  • 更改root用户的密码
  • 创建一个新用户
  • 创建新用户的密码
  • 赋予新用户root权限
  • (可选)更改 SSH 守护程序侦听的端口
  • (可选)限制 root SSH 登录
  • (可选)明确允许我们的新用户

修改目标以解决环境问题

对于使用 cloud-config 文件创建的服务器,我们将不得不稍微修改我们的目标。 在服务器的整个生命周期内,系统的 any 用户都可以访问通过 cloud-config 文件传入的任何信息。

这引入了许多需要理解和解决的安全问题。 要记住的一些事情是:

  • 系统上的每个用户都可以访问 cloud-config 中传递的任何信息。 不要在您的 cloud-config 文件中放置任何机密内容。
  • 您可以为现有用户设置密码,但必须以纯文本形式传递。
  • 对于新用户,您可以传入密码的散列版本,但这些散列可以很容易地用现代硬件破解。

考虑到这些,我们的设置应该尽一切可能避免在 cloud-config 文件中以任何形式提交密码。 我们可以调整我们的目标以适应我们的部署环境的特定需求。

我们调整后的策略将如下所示:

  • 通过 cloud-config 不为 root 帐户设置密码并且不提供 SSH 密钥(通过 DigitalOcean 界面添加的任何 SSH 密钥仍将照常添加)
  • 创建一个新用户
  • 不为新用户帐户设置密码
  • 为新用户帐户设置 SSH 访问
  • 授予新用户无密码 sudo 权限以进行管理更改。
  • (可选)更改 SSH 守护程序侦听的端口
  • (可选)限制 root SSH 登录(特别是如果您不通过 DigitalOcean 界面包含 SSH 密钥)
  • (可选)明确允许我们的新用户

除了删除两个账号的密码外,这里最大的改变是允许新账号在不输入账号密码的情况下使用sudo。 这是必要的,因为我们不允许 root 登录,并且我们没有为新用户设置帐户密码。

新用户登录后,他们将可以自由地为自己安全地设置密码,并根据需要修改 sudo 权限以要求输入密码。

考虑到这些调整后的目标,让我们开始吧。

使用云配置文件

cloud-config 文件基本上是理解某些指令的 YAML 文件。 YAML 是一种数据序列化格式,旨在非常易于阅读,使其易于理解和编辑。

YAML 文件依赖于一些格式化规则:

  • 带有空格的缩进表示项目之间的结构和关系。 更多缩进的项目是第一个项目的子项目,它们上方的缩进级别较低。
  • 列表成员可以通过前导破折号来标识。
  • 通过使用冒号 (:) 后跟空格和值来创建关联数组条目。
  • 文本块是缩进的。 要指示应按原样读取块,并保持格式不变,请在块前使用竖线字符 (|)。

cloud-config 文件的第一行必须包含一个特殊标识符,以便 cloud-init 程序知道该文件是 cloud-config 文件。 这看起来像这样:

#cloud-config

这必须单独放在第一行。 创建服务器时必须提供cloud-config文件。 这可以通过两种不同的方式来实现。

请记住,元数据服务仅在部署了云 1.5 的区域中可用。 此外,使用 user-data 字段所需的 cloud-init 版本目前仅在 Ubuntu 14.04 和 CentOS 7 中可用,以及基于这些版本的应用程序映像。

通过控制面板界面,有一个可选的复选框来启用用户数据。 当您选择此项时,将显示一个文本框,您可以在其中粘贴 cloud-config 文件:

如果您使用 API,则在创建请求期间传入的 JSON 对象可以使用名为 user_data 的字段。 例如,您可以传入一个类似于以下内容的 JSON 对象:

{
    "name": "test",
    "private_networking": true,
    "region": "nyc3",
    "size": "512mb",
    "image": "ubuntu-14-04-x64",
    "user_data":"#cloud-config
        config_data
        more_config"
    "ssh_keys":[ 12345,56789 ]
}

这两种方法在实践中的工作原理完全相同,因此请使用最适合您的方法。

设置新用户帐户

我们需要做的第一件事是配置我们的新用户帐户。

几乎所有的工作都将在这里进行。 root 帐户默认没有密码,因此我们不必在那里“取消设置”任何密码。

创建新用户

要创建新用户,我们使用 users 指令。 这将包含我们要创建的所有新帐户的列表。 由于我们只创建一个帐户,我们将有一个列表。 为了遵循我们链接到的指南,我们将这个新帐户称为 demo

请记住,我们必须在第一行单独使用 #cloud-config 开始我们的 cloud-config 文件。 到目前为止,我们的文件将如下所示:

#cloud-config
users:
  - name: demo

如果我们想添加其他用户,我们可以通过在下方放置一个项目并与该项目水平对齐,再次以破折号开头,如下所示:

#cloud-config
users:
  - name: demo
  - name: second_user

每个破折号表示一个单独的用户帐户,我们可以在该帐户下添加用户的详细信息(我们稍后会这样做)。 虽然我们只创建了一个用户,所以我们不会在本指南中包含第二行。

添加授权密钥

为了在没有密码的情况下登录这个新帐户,我们需要提供一个或多个 SSH 公钥。 这些将被添加到新用户主目录中 .ssh 目录中的 authorized_keys 文件中。

这是通过 ssh-authorized-keys 指令完成的,它是 users 条目的子项。 基本上这意味着我们将它与我们的 name 指令对齐,但不要给它一个破折号,因为它不是新用户条目的开始。

ssh-authorized-keys 条目实际上需要一个键列表。 这允许您向文件添加多个 SSH 公钥。 例如,如果您的笔记本电脑、台式机和工作计算机有一个 SSH 密钥对,您可以将所有这些作为单独的项目添加到 ssh-authorized-keys 列表中。

要获取本地计算机的公钥的内容,您可以键入:

cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCv60WjxoM39LgPDbiW7ne3gu18q0NIVv0RE6rDLNal1quXZ3nqAlANpl5qmhDQ+GS/sOtygSG4/9aiOA4vXO54k1mHWL2irjuB9XbXr00+44vSd2q/vtXdGXhdSMTf4/XK17fjKSG/9y3yD6nml6q9XgQxx9Vf/IkaKdlK0hbC1ds0+8h83PTb9dF3L7hf3Ch/ghvj5++tWJFdFeG+VI7EDuKNA4zL8C5FdYYWFA88YAmM8ndjA5qCjZXIIeZvZ/z9Kpy6DL0QZ8T3NsxRKapEU3nyiIuEAmn8fbnosWcsovw0IS1Hz6HsjYo4bu/gA82LWt3sdRUBZ/7ZsVD3ELip user@example.com

然后,您可以将完整的内容作为一个项目粘贴到我们的 ssh-authorized-keys 条目下。 SSH 公钥可以公开发布,因此这并不代表安全风险:

#cloud-config
users:
  - name: demo
    ssh-authorized-keys:
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCv60WjxoM39LgPDbiW7ne3gu18q0NIVv0RE6rDLNal1quXZ3nqAlANpl5qmhDQ+GS/sOtygSG4/9aiOA4vXO54k1mHWL2irjuB9XbXr00+44vSd2q/vtXdGXhdSMTf4/XK17fjKSG/9y3yD6nml6q9XgQxx9Vf/IkaKdlK0hbC1ds0+8h83PTb9dF3L7hf3Ch/ghvj5++tWJFdFeG+VI7EDuKNA4zL8C5FdYYWFA88YAmM8ndjA5qCjZXIIeZvZ/z9Kpy6DL0QZ8T3NsxRKapEU3nyiIuEAmn8fbnosWcsovw0IS1Hz6HsjYo4bu/gA82LWt3sdRUBZ/7ZsVD3ELip user@example.com

如果您想添加其他密钥,可以通过添加另一个破折号后跟第二个公钥来完成:

#cloud-config
users:
  - name: demo
    ssh-authorized-keys:
      - key_one
      - key_two

在此处添加您希望用于登录此帐户的任何密钥。

设置 Sudo 访问

下一步是配置 sudo 访问我们的新帐户。 重申一下,我们将配置无密码 sudo 访问,因为由于安全限制,我们不会为此帐户设置密码。

要配置访问权限,我们实际上将执行两个单独的步骤。

首先,我们将创建要用于 sudoers 文件的条目。 我们的更改实际上将写入 /etc/sudoers.d 目录中的一个单独文件,其中 /etc/sudoers 在解析时包括在内。

我们需要创建的条目不需要包含用户名,因为 cloud-init 足够聪明,可以从条目信息中找出帐户名称。 我们需要使用的指令是 sudo,它与我们的其他 users 级别的指令对齐。

对于我们的指南,由于我们正在配置无密码 sudo 功能,因此将如下所示:

#cloud-config
users:
  - name: demo
    ssh-authorized-keys:
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCv60WjxoM39LgPDbiW7ne3gu18q0NIVv0RE6rDLNal1quXZ3nqAlANpl5qmhDQ+GS/sOtygSG4/9aiOA4vXO54k1mHWL2irjuB9XbXr00+44vSd2q/vtXdGXhdSMTf4/XK17fjKSG/9y3yD6nml6q9XgQxx9Vf/IkaKdlK0hbC1ds0+8h83PTb9dF3L7hf3Ch/ghvj5++tWJFdFeG+VI7EDuKNA4zL8C5FdYYWFA88YAmM8ndjA5qCjZXIIeZvZ/z9Kpy6DL0QZ8T3NsxRKapEU3nyiIuEAmn8fbnosWcsovw0IS1Hz6HsjYo4bu/gA82LWt3sdRUBZ/7ZsVD3ELip user@example.com
    sudo: ['ALL=(ALL) NOPASSWD:ALL']

这将在 /etc/sudoers.d 目录中创建一个名为 90-cloud-init-users 的文件。 在此文件中,条目将如下所示:

demo ALL=(ALL) NOPASSWD:ALL

我们要做的第二件事实际上是将我们的用户添加到 sudo 组。 这不是绝对必要的,因为我们有一个特定于我们的新帐户的条目,它由 sudo 解析,但它为我们提供了更大的灵活性。

稍后,我们可能希望为我们的用户手动设置一个密码,并要求该密码用于 sudo 命令。 如果我们的用户已经在 sudo 组中,我们所要做的就是设置密码并删除 90-cloud-init-users 文件中的条目。

要添加补充组,我们可以使用 groups 指令:

#cloud-config
users:
  - name: demo
    ssh-authorized-keys:
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCv60WjxoM39LgPDbiW7ne3gu18q0NIVv0RE6rDLNal1quXZ3nqAlANpl5qmhDQ+GS/sOtygSG4/9aiOA4vXO54k1mHWL2irjuB9XbXr00+44vSd2q/vtXdGXhdSMTf4/XK17fjKSG/9y3yD6nml6q9XgQxx9Vf/IkaKdlK0hbC1ds0+8h83PTb9dF3L7hf3Ch/ghvj5++tWJFdFeG+VI7EDuKNA4zL8C5FdYYWFA88YAmM8ndjA5qCjZXIIeZvZ/z9Kpy6DL0QZ8T3NsxRKapEU3nyiIuEAmn8fbnosWcsovw0IS1Hz6HsjYo4bu/gA82LWt3sdRUBZ/7ZsVD3ELip user@example.com
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    groups: sudo

这将更容易过渡到更传统的 sudo 设置。 我们将在本指南的末尾向您展示如何执行此操作。

设置外壳环境

默认情况下,新创建的用户将他们的默认 shell 设置为非常基本的 /bin/sh shell。

这是一个比大多数人习惯的更精简的环境,所以我们想为我们的新用户手动指定一个 bash shell 环境。

这可以通过 users 级别项中的 shell 指令来完成。 我们需要做的就是将它指向 bash 可执行文件的完整路径:

#cloud-config
users:
  - name: demo
    ssh-authorized-keys:
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCv60WjxoM39LgPDbiW7ne3gu18q0NIVv0RE6rDLNal1quXZ3nqAlANpl5qmhDQ+GS/sOtygSG4/9aiOA4vXO54k1mHWL2irjuB9XbXr00+44vSd2q/vtXdGXhdSMTf4/XK17fjKSG/9y3yD6nml6q9XgQxx9Vf/IkaKdlK0hbC1ds0+8h83PTb9dF3L7hf3Ch/ghvj5++tWJFdFeG+VI7EDuKNA4zL8C5FdYYWFA88YAmM8ndjA5qCjZXIIeZvZ/z9Kpy6DL0QZ8T3NsxRKapEU3nyiIuEAmn8fbnosWcsovw0IS1Hz6HsjYo4bu/gA82LWt3sdRUBZ/7ZsVD3ELip user@example.com
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    groups: sudo
    shell: /bin/bash

我们已经完成了新的用户配置。 我们现在可以继续执行锁定 SSH 守护程序的可选步骤。

配置和锁定 SSH 守护程序(可选)

后续步骤可用于提高安全性。 您可以根据需要实施其中的任何一个或全部。 查看我们正在自动化的指南以获取有关这些选项的更多信息。 我们将向您展示如何使用两种不同的方法来实现每个项目。

我们需要进行的所有更改都将在 /etc/ssh/sshd_config 文件中。 重申一下,我们有兴趣进行的更改是:

  • (可选)更改 SSH 守护程序侦听的端口
  • (可选)限制 root SSH 登录(特别是如果您不通过 DigitalOcean 界面包含 SSH 密钥)
  • (可选)明确允许我们的新用户

这些设置可以通过分别在 sshd_config 文件中进行这些更改来实现:

  • 端口 4444
  • PermitRootLogin
  • AllowUsers 演示

有两种方法可以进行这些更改。 第一个是通过在我们的 cloud-config 文件中提供整个配置文件来完全重写文件。 第二个是使用常见的 Linux 文本实用程序战略性地进行更改。

两者各有优势,都在 cloud-config 中展示了不同的指令。 我们将依次介绍每个。

通过提供新的配置文件来配置 SSH 守护程序

进行我们想要的更改的第一个策略是用我们想要的确切内容完全重写文件。

这使我们可以完全控制文件,而不管默认情况下有什么可用的。 该方法是直截了当的,很容易预测我们行动的结果。

要将新文件写入磁盘,我们可以使用 write_files 指令。 这是一个顶级指令,所以它应该放在我们之前工作的 users 部分之外。

我们提供了一个我们想要写入的文件列表(每个项目都用破折号表示)。

#cloud-config
users:
  - name: demo
    ssh-authorized-keys:
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCv60WjxoM39LgPDbiW7ne3gu18q0NIVv0RE6rDLNal1quXZ3nqAlANpl5qmhDQ+GS/sOtygSG4/9aiOA4vXO54k1mHWL2irjuB9XbXr00+44vSd2q/vtXdGXhdSMTf4/XK17fjKSG/9y3yD6nml6q9XgQxx9Vf/IkaKdlK0hbC1ds0+8h83PTb9dF3L7hf3Ch/ghvj5++tWJFdFeG+VI7EDuKNA4zL8C5FdYYWFA88YAmM8ndjA5qCjZXIIeZvZ/z9Kpy6DL0QZ8T3NsxRKapEU3nyiIuEAmn8fbnosWcsovw0IS1Hz6HsjYo4bu/gA82LWt3sdRUBZ/7ZsVD3ELip user@example.com
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    groups: sudo
    shell: /bin/bash
write_files:
  - item_one
  - item_two

在我们的例子中,我们只会写一个文件。 对于每个文件,我们提供有关我们想要制作的变更的详细信息。 例如,您可以使用的参数有 pathcontentownerpermissions,甚至是 encoding

默认情况下,使用这种方法创建的文件的所有者是root,权限是644,这正是我们想要的。 所以我们只需要提供 pathcontent 指令。

path 只是文件系统中写入文件的位置。

对于 content,我们需要提供文件的全部内容,按原样编写。 请记住,我们可以使用竖线字符 (|) 来传递将保持其格式的文本块。

对于我们的 sshd_config 文件的内容,我们将只使用默认内容,去掉注释(为简洁起见),以及我们想要进行的更改。 重写文件的完整部分如下所示:

#cloud-config
users:
  - name: demo
    ssh-authorized-keys:
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCv60WjxoM39LgPDbiW7ne3gu18q0NIVv0RE6rDLNal1quXZ3nqAlANpl5qmhDQ+GS/sOtygSG4/9aiOA4vXO54k1mHWL2irjuB9XbXr00+44vSd2q/vtXdGXhdSMTf4/XK17fjKSG/9y3yD6nml6q9XgQxx9Vf/IkaKdlK0hbC1ds0+8h83PTb9dF3L7hf3Ch/ghvj5++tWJFdFeG+VI7EDuKNA4zL8C5FdYYWFA88YAmM8ndjA5qCjZXIIeZvZ/z9Kpy6DL0QZ8T3NsxRKapEU3nyiIuEAmn8fbnosWcsovw0IS1Hz6HsjYo4bu/gA82LWt3sdRUBZ/7ZsVD3ELip user@example.com
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    groups: sudo
    shell: /bin/bash
write_files:
  - path: /etc/ssh/sshd_config
    content: |
         Port 4444
         Protocol 2
         HostKey /etc/ssh/ssh_host_rsa_key
         HostKey /etc/ssh/ssh_host_dsa_key
         HostKey /etc/ssh/ssh_host_ecdsa_key
         HostKey /etc/ssh/ssh_host_ed25519_key
         UsePrivilegeSeparation yes
         KeyRegenerationInterval 3600
         ServerKeyBits 1024
         SyslogFacility AUTH
         LogLevel INFO
         LoginGraceTime 120
         PermitRootLogin no
         StrictModes yes
         RSAAuthentication yes
         PubkeyAuthentication yes
         IgnoreRhosts yes
         RhostsRSAAuthentication no
         HostbasedAuthentication no
         PermitEmptyPasswords no
         ChallengeResponseAuthentication no
         X11Forwarding yes
         X11DisplayOffset 10
         PrintMotd no
         PrintLastLog yes
         TCPKeepAlive yes
         AcceptEnv LANG LC_*
         Subsystem sftp /usr/lib/openssh/sftp-server
         UsePAM yes
         AllowUsers demo

这将用我们提供的新内容完全替换 /etc/ssh/sshd_config 的内容。 这是 Ubuntu 的默认 sshd_config 文件,仅修改了我们上面提到的项目。

这是对 SSH 守护程序进行更改的一种方法。

通过集中更改配置 SSH 守护程序

我们可以修改 sshd_config 文件的第二种方法是通过集中编辑。 Linux 系统带有各种强大的文本操作工具,我们可以利用这些工具只进行我们需要的更改。

要运行任意命令,我们将使用一个名为 runcmd 的指令,它允许我们在系统上运行任何命令。 每个命令都将是指令下的一个列表项。 这些可以作为表示整个命令的字符串给出,也可以作为包含命令和所有选项作为元素的数组给出。

我们将使用 sed 命令,该命令用于字符串替换。 尽管您可以将多个操作传递给单个 sed 命令,但我们将为每个 sed 命令执行单个操作。 这将使我们能够更轻松地解决任何问题。 我们所有的 sed 命令都将编辑 sshd_config 文件。

我们的第一个 sed 命令将更改配置监听端口的行。 我们将通过搜索以“端口”开头的行来识别这一点。 我们将告诉 sed 用我们的 Port 4444 配置替换整行(由正则表达式 ^.*$ 指定):

#cloud-config
users:
  - name: demo
    ssh-authorized-keys:
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCv60WjxoM39LgPDbiW7ne3gu18q0NIVv0RE6rDLNal1quXZ3nqAlANpl5qmhDQ+GS/sOtygSG4/9aiOA4vXO54k1mHWL2irjuB9XbXr00+44vSd2q/vtXdGXhdSMTf4/XK17fjKSG/9y3yD6nml6q9XgQxx9Vf/IkaKdlK0hbC1ds0+8h83PTb9dF3L7hf3Ch/ghvj5++tWJFdFeG+VI7EDuKNA4zL8C5FdYYWFA88YAmM8ndjA5qCjZXIIeZvZ/z9Kpy6DL0QZ8T3NsxRKapEU3nyiIuEAmn8fbnosWcsovw0IS1Hz6HsjYo4bu/gA82LWt3sdRUBZ/7ZsVD3ELip user@example.com
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    groups: sudo
    shell: /bin/bash
runcmd:
  - sed -i -e '/^Port/s/^.*$/Port 4444/' etc/ssh/sshd_config

我们的下一个 sed 行将通过在行首搜索该字符串来修改“PermitRootLogin”指令。 再一次,我们将替换整行,这次用 PermitRootLogin no

#cloud-config
users:
  - name: demo
    ssh-authorized-keys:
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCv60WjxoM39LgPDbiW7ne3gu18q0NIVv0RE6rDLNal1quXZ3nqAlANpl5qmhDQ+GS/sOtygSG4/9aiOA4vXO54k1mHWL2irjuB9XbXr00+44vSd2q/vtXdGXhdSMTf4/XK17fjKSG/9y3yD6nml6q9XgQxx9Vf/IkaKdlK0hbC1ds0+8h83PTb9dF3L7hf3Ch/ghvj5++tWJFdFeG+VI7EDuKNA4zL8C5FdYYWFA88YAmM8ndjA5qCjZXIIeZvZ/z9Kpy6DL0QZ8T3NsxRKapEU3nyiIuEAmn8fbnosWcsovw0IS1Hz6HsjYo4bu/gA82LWt3sdRUBZ/7ZsVD3ELip user@example.com
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    groups: sudo
    shell: /bin/bash
runcmd:
  - sed -i -e '/^Port/s/^.*$/Port 4444/' /etc/ssh/sshd_config
  - sed -i -e '/^PermitRootLogin/s/^.*$/PermitRootLogin no/' /etc/ssh/sshd_config

下一个 sed 命令将在文件末尾添加一行,因为文件中当前没有“AllowUsers”指令。 我们通过匹配最后一行(由“$”指定)并附加我们需要的行来做到这一点。

之后,我们需要重新启动 SSH 守护程序,以便传播我们的更改。 我们可以使用 Upstart 的“restart”命令轻松做到这一点:

#cloud-config
users:
  - name: demo
    ssh-authorized-keys:
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCv60WjxoM39LgPDbiW7ne3gu18q0NIVv0RE6rDLNal1quXZ3nqAlANpl5qmhDQ+GS/sOtygSG4/9aiOA4vXO54k1mHWL2irjuB9XbXr00+44vSd2q/vtXdGXhdSMTf4/XK17fjKSG/9y3yD6nml6q9XgQxx9Vf/IkaKdlK0hbC1ds0+8h83PTb9dF3L7hf3Ch/ghvj5++tWJFdFeG+VI7EDuKNA4zL8C5FdYYWFA88YAmM8ndjA5qCjZXIIeZvZ/z9Kpy6DL0QZ8T3NsxRKapEU3nyiIuEAmn8fbnosWcsovw0IS1Hz6HsjYo4bu/gA82LWt3sdRUBZ/7ZsVD3ELip user@example.com
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    groups: sudo
    shell: /bin/bash
runcmd:
  - sed -i -e '/^Port/s/^.*$/Port 4444/' /etc/ssh/sshd_config
  - sed -i -e '/^PermitRootLogin/s/^.*$/PermitRootLogin no/' /etc/ssh/sshd_config
  - sed -i -e '$aAllowUsers demo' /etc/ssh/sshd_config
  - restart ssh

这应该足以对我们的文件进行所需的编辑并重新启动服务。

完成的产品

现在,我们已经使用 cloud-config 文件完成了所有调整后的目标。 您可以使用控制面板创建服务器,也可以使用 API 启动服务器。

如果您选择使用 API,示例数据负载可能如下所示:

{"name": "your_droplet_name",
"private_networking": true,
"region": "nyc3",
"size": "512mb",
"image": "ubuntu-14-04-x64",
"user-data": "#cloud-config
users:
  - name: demo
    ssh-authorized-keys:
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCv60WjxoM39LgPDbiW7ne3gu18q0NIVv0RE6rDLNal1quXZ3nqAlANpl5qmhDQ+GS/sOtygSG4/9aiOA4vXO54k1mHWL2irjuB9XbXr00+44vSd2q/vtXdGXhdSMTf4/XK17fjKSG/9y3yD6nml6q9XgQxx9Vf/IkaKdlK0hbC1ds0+8h83PTb9dF3L7hf3Ch/ghvj5++tWJFdFeG+VI7EDuKNA4zL8C5FdYYWFA88YAmM8ndjA5qCjZXIIeZvZ/z9Kpy6DL0QZ8T3NsxRKapEU3nyiIuEAmn8fbnosWcsovw0IS1Hz6HsjYo4bu/gA82LWt3sdRUBZ/7ZsVD3ELip user@example.com
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    groups: sudo
    shell: /bin/bash
runcmd:
  - sed -i -e '/^Port/s/^.*$/Port 4444/' /etc/ssh/sshd_config
  - sed -i -e '/^PermitRootLogin/s/^.*$/PermitRootLogin no/' /etc/ssh/sshd_config
  - sed -i -e '$aAllowUsers demo' /etc/ssh/sshd_config
  - restart ssh"}

故障排除

如果您在使 cloud-config 文件正常工作时遇到问题,您可以检查日志文件中的线索。

这些位于:

  • /var/log/cloud-init.log:cloud-init处理配置文件的实际进程日志。
  • /var/log/cloud-init-output.log:配置处理产生的任何输出都可以在这里找到。

您通常可以通过使用 grep 搜索这些文件来找到有关发生的事情的一些有用信息。

如果你遇到了因为一些配置问题而无法登录你创建的服务器的情况,最好将服务器销毁,然后重新启动。 为了进行故障排除,有时需要在 cloud-config 文件中临时设置一个带有 root 密码的测试服务器,以便您查看问题所在。

这可以通过在 cloud-config 中包含类似的内容来完成:

#cloud-config
chpasswd:
  list: |
    root:yourpassword
  expire: False
. . .

这将允许您使用不依赖 SSH 的 DigitalOcean 控制台登录。 请记住,您在此处放置的任何密码都将在系统的整个生命周期内对您服务器上的每个用户都是可读的,因此在找出问题所在后销毁此 Droplet。 然后,您可以使用更正后的 cloud-config 文件启动另一台服务器。

设置传统的 Sudo 访问

如果您想在部署服务器后配置更常规的密码验证 sudo 访问,您可以轻松执行以下步骤:

首先,您需要为新帐户设置密码。 无需 输入当前密码(不存在)的唯一方法是通过 sudo。 您必须在命令末尾指定新用户帐户的名称才能不设置 root 密码:

sudo passwd demo

现在您已经有了帐户密码,请确认您实际上是在 sudo 组中。 这可以通过键入:

groups
demo sudo

如果您尚未加入 sudo 组,您可以通过键入以下内容添加自己:

sudo usermod -a -G sudo demo

现在,使用 visudo 命令编辑 90-cloud-init-users 文件,将文件作为参数传递:

sudo visudo -f /etc/sudoers.d/90-cloud-init-users

注释掉或删除与您的用户关联的行:

#demo ALL=(ALL) NOPASSWD:ALL

保存并关闭文件。 您的帐户现在需要您的密码才能执行 sudo 命令。

结论

使用 cloud-config 文件完成服务器的初始配置可以很容易,从长远来看可以节省您的时间。 这些文件很容易调整,并且构建许多不同的配置可以为您提供快速设置服务器的极大灵活性。

通过在机器上线后将 cloud-config 与更传统的配置管理系统相结合,您可以快速轻松地将新机器准确地带入所需的状态。