介绍
服务器自动化现在在系统管理中起着至关重要的作用,因为现代应用环境的可调用性质。 配置管理 工具如 Ansible 通常用于通过为新服务器建立标准程序来简化服务器设置的自动化过程,同时也减少了与手动设置相关的人为错误。
Ansible提供了一个简单的架构,不需要在节点上安装特殊软件,它还提供了一组强大的功能和内置模块,可方便编写自动化脚本。
本指南解释了如何使用 Ansible 来自动化我们 Ubuntu 20.04 服务器的初始服务器设置指南中的步骤。
前提条件
为了执行本指南中播放书提供的自动设置,您将需要:
- One Ansible 控制节点:一个安装在 Ansible 的 Ubuntu 20.04 机器,并配置以使用 SSH 密钥连接到您的 Ansible 主机。 确保控制节点具有具有 sudo 权限的常规用户和启用防火墙,如我们在 初始服务器设置 指南中所解释的那样。 要设置 Ansible,请遵循我们在 如何在 Ubuntu 20.04 上安装和配置 Ansible 的指南。
- 一个清洁安装 Ubuntu 20.04 的远程服务器:在这个服务器上不需要任何预先设置,但您必须从上面提到的 Ansible 控制节点获得 SSH 访问该服务器。
这个 Playbook 能做什么?
此 Ansible 播放本提供了通过 Ubuntu 20.04 初始服务器设置指南和 Ubuntu 20.04 上设置 SSH 密钥的指南中描述的程序手动运行的替代方案,每次你启动服务器。
运行此播放簿将在您的 Ansible 主机上执行以下操作:
安装aptitude
,这是Ansible所偏爱的apt
包管理器的替代方案
。2创建一个新的 sudo用户并设置无密码的sudo
。3复制一个本地SSH公共密钥,并将其纳入到远程主机上的新管理用户的autorized_keys
文件中
。4禁用对 root用户的基于密码的身份验证
5.安装系统包
6.设置UFW防火墙只允许SSH连接并拒绝任何其他请求
一旦播放簿完成运行,您将有一个新的用户,您可以使用它来登录服务器。
首先,在您的 Ansible 控制节点服务器上登录一个具有sudo
功能的用户。
步骤 1 – 准备您的 Ansible 控制节点
在您的 Ansible 控制节点服务器上,将您的 Ansible 远程主机服务器的 IP 添加到您的 Ansible 库存文件中。
1sudo nano /etc/ansible/hosts
将您的 Ansible 库存文件打开. 将您的 Ansible 远程主机服务器的 IP 添加到[服务器]
块中:
1[label /etc/ansible/hosts]
2[servers]
3server1 ansible_host=your_remote_server_ip
4
5. . .
现在,您将测试并验证此 Ansible 控制节点与您的 Ansible 远程主机服务器之间的 SSH 连接:
1ssh root@your_remote_server_ip
接受身份验证请求,并在提示时输入您的密码.一旦您验证了 SSH 连接,请按CTRL+D
关闭连接并返回控制节点。
步骤2 - 准备你的剧本
「playbook.yml」文件是您所有 tasks 都定义的文件。 任务是您可以使用 Ansible 播放簿自动化操作的最小单位,但首先使用您偏好的文本编辑器创建播放簿文件:
1nano playbook.yml
这样会打开一个空的 YAML 文件. 在进入将任务添加到播放簿之前,请先添加以下内容:
1[label playbook.yml]
2[environment local]
3---
4- hosts: all
5 become: true
6 vars:
7 created_username: sammy
您可以自由地用您选择的用户名更换。
几乎每本你遇到的读本都会以类似的声明开始。‘主机’声明了 Ansible 控制节点将针对该读本的哪些服务器。
vars
允许您将数据存储为变量. 如果您决定在未来更改这个用户名,您只需要在文件中编辑这个单行。
<$>[注] 注: 如果你想看到播放本文件的最终完成状态,跳到 步骤 8。
步骤 3 — 将技能安装任务添加到您的游戏簿
默认情况下,Ansible 会将任务同步执行,顺序从播放簿的顶部到底部,这意味着任务排序很重要,您可以安全地假设一个任务在下一个任务开始之前完成执行。
本剧本中的所有任务都可以单独站立,并在你的其他剧本中重复使用。
添加你的第一个安装aptitude
的任务,这是一个与Linux包管理器接口的工具:
1[label playbook.yml]
2[environment local]
3 tasks:
4 - name: Install aptitude
5 apt:
6 name: aptitude
7 state: latest
8 update_cache: true
在这里,您正在使用apt
Ansible 内置的 module 来指导 Ansible 安装aptitude
。 Ansible 中的模块是执行操作的捷径,否则您将不得不运行作为原始 bash 命令。
步骤 4 — 将 Sudo 用户设置任务添加到您的 Playbook
避免广泛使用 root用户是很好的做法,您可以通过添加:自动创建获得sudo
特权的用户:
1[label playbook.yml]
2[environment local]
3 - name: Setup passwordless sudo
4 lineinfile:
5 path: /etc/sudoers
6 state: present
7 regexp: '^%sudo'
8 line: '%sudo ALL=(ALL) NOPASSWD: ALL'
9 validate: '/usr/sbin/visudo -cf %s'
10
11 - name: Create a new regular user with sudo privileges
12 user:
13 name: "{{ created_username }}"
14 state: present
15 groups: sudo
16 append: true
17 create_home: true
您正在使用lineinfile
Ansible 模块来瞄准并替换文件中的特定行. 在这种情况下,您正在使用 regex 瞄准sudoers
文件中的特定行,然后修改它以允许sudo
的无密码使用。
为了利用这一点,您正在使用用户
模块添加一个新用户。Ansible将确保这个用户被创建,如果不是已经存在的,则该用户属于sudo
组,而不是从其他组中删除,并创建一个主目录。
<$>[注] 注: 请确保您包含指示变量的曲线周围的引文。
步骤 5 – 将 SSH 密钥设置添加到 Playbook 并禁用根密码任务
Ansible 在假设您正在使用 SSH 密钥的情况下运行。强烈建议并通常是良好的做法,将 SSH 密钥的使用与禁用 root 密码身份验证结合起来。
1[label playbook.yml]
2[environment local]
3 - name: Set authorized key for remote user
4 ansible.posix.authorized_key:
5 user: "{{ created_username }}"
6 state: present
7 key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"
8
9 - name: Disable password authentication for root
10 lineinfile:
11 path: /etc/ssh/sshd_config
12 state: present
13 regexp: '^#?PermitRootLogin'
14 line: 'PermitRootLogin prohibit-password'
如果您提供用户名和密钥的位置,则可以使用autorized_key
模块,在这里,使用Ansible的lookup
函数构建了通往密钥的路径。
lineinfile
模块用于搜索和替换sshd_config
中的行,以禁用 root的密码身份验证,限制其权限以增强安全性。
步骤 6 — 将包装安装任务添加到您的 Playbook
Ansible可以确保某些软件包始终安装在您的服务器上,而不是在每个软件包上调用apt install
或将其分成多个任务,您可以列出您想要的所有软件包:
1[label playbook.yml]
2[environment local]
3 - name: Update apt and install required system packages
4 apt:
5 pkg:
6 - curl
7 - vim
8 - git
9 - ufw
10 state: latest
11 update_cache: true
您可以添加或删除您喜欢的包,这将确保所有包不仅存在,而且在最新版本上,并且在调用apt
更新后完成。
步骤 7 — 将防火墙设置任务添加到您的Playbook中
防火墙对于面向互联网的任何服务器都不可或缺,您可以使用 Ansible 确保 UFW(不复杂防火墙)通过添加:
1[label playbook.yml]
2[environment local]
3 - name: UFW - Allow SSH connections
4 community.general.ufw:
5 rule: allow
6 name: OpenSSH
7
8 - name: UFW - Enable and deny by default
9 community.general.ufw:
10 state: enabled
11 default: deny
ufw
模块首先确保允许通过SSH访问,然后,该模块允许您的防火墙在默认情况下拒绝所有其他流量到您的服务器。
步骤8 - 审查您的完整游戏簿
您的播放簿应该大致如下,根据您的自定义而有所不同:
1[label playbook.yml]
2[environment local]
3---
4- hosts: all
5 become: true
6 vars:
7 created_username: sammy
8
9 tasks:
10 - name: Install aptitude
11 apt:
12 name: aptitude
13 state: latest
14 update_cache: true
15
16 - name: Setup passwordless sudo
17 lineinfile:
18 path: /etc/sudoers
19 state: present
20 regexp: '^%sudo'
21 line: '%sudo ALL=(ALL) NOPASSWD: ALL'
22 validate: '/usr/sbin/visudo -cf %s'
23
24 - name: Create a new regular user with sudo privileges
25 user:
26 name: "{{ created_username }}"
27 state: present
28 groups: sudo
29 append: true
30 create_home: true
31
32 - name: Set authorized key for remote user
33 ansible.posix.authorized_key:
34 user: "{{ created_username }}"
35 state: present
36 key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"
37
38 - name: Disable password authentication for root
39 lineinfile:
40 path: /etc/ssh/sshd_config
41 state: present
42 regexp: '^#?PermitRootLogin'
43 line: 'PermitRootLogin prohibit-password'
44
45 - name: Update apt and install required system packages
46 apt:
47 pkg:
48 - curl
49 - vim
50 - git
51 - ufw
52 state: latest
53 update_cache: true
54
55 - name: UFW - Allow SSH connections
56 community.general.ufw:
57 rule: allow
58 name: OpenSSH
59
60 - name: UFW - Enable and deny by default
61 community.general.ufw:
62 state: enabled
63 default: deny
<$>[注] 注: 这是一个温和的提醒,要记住你的入口。如果你遇到错误,这很可能是罪魁祸首。YAML建议使用2个空间作为入口,正如本例所做的。
一旦您对播放书满意,您可以退出文本编辑器并保存。
步骤 9 – 首次运行 Playbook
您现在已经准备好在一个或多个服务器上运行此播放簿. 大多数播放簿默认配置为在您的库存中的每个服务器上执行,但您将此时指定您的服务器。
若要只在「server1」上執行播放簿,以「root」方式連接,您可以使用下列命令:
1[environment local]
2ansible-playbook playbook.yml -l server1 -u root -k
「-l」旗指明您的服务器,而「-u」旗指明哪些用户要登录远程服务器. 由于您尚未设置远程服务器,所以 root是您唯一的选择。
你会得到类似于此的输出:
1[secondary_label Output]
2
3. . .
4
5TASK [UFW - Allow SSH connections] ***************************************************************************************************************************************************************************************************************************
6changed: [server1]
7
8TASK [UFW - Enable and deny by default] **********************************************************************************************************************************************************************************************************************
9changed: [server1]
10
11PLAY RECAP ***************************************************************************************************************************************************************************************************************************************************
12server1 : ok=9 changed=8 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
这表明您的服务器设置已经完成!您的输出不一定完全相同,但重要的是您有零故障。
现在你已经完成了播放本的第一个设置,所有后续的面向呼叫可以用用户sammy
和没有-k
旗进行:
1[environment local]
2ansible-playbook playbook.yml -l server1 -u sammy
您还将能够登录到服务器:
1[environment local]
2ssh sammy@your_remote_server_ip
请记住,用created_username
变量定义的用户代替 sammy,并用服务器的主机名或 IP 地址代替 server_host_or_IP。
在登录到服务器后,您可以检查UFW防火墙的活跃规则,以确认它是否正确配置:
1[environment second]
2sudo ufw status
你应该得到类似于此的输出:
1[secondary_label Output]
2[environment second]
3Status: active
4
5To Action From
6-- ------ ----
7OpenSSH ALLOW Anywhere
8OpenSSH (v6) ALLOW Anywhere (v6)
这意味着UFW防火墙已成功启用,因为这是播放书中的最后一项任务,它确认播放书已在这个服务器上完全执行。
结论
自动化初始服务器设置可以节省时间,同时确保您的服务器遵循标准配置,可以根据您的需求进行改进和定制。
在本指南中,您展示了如何使用Ansible来自动化在新服务器上执行的初始任务,例如创建具有sudo
访问的非root用户,启用UFW并禁用基于密码的远程 root登录。
有关如何运行 Ansible 播放簿的更多信息,请参阅我们的 Ansible Cheat Sheet Guide。
如果您想在本图书中添加新任务,以进一步定制初始服务器设置,请参阅我们介绍的 Ansible 指南 配置管理 101:编写 Ansible 图书。