教程:安全手册(第一部分)

关于教程的注意事项:我们鼓励用户尝试教程,但是我们的团队并不完全支持我们 – 当出现问题时,我们不能总是提供支持。在继续之前,请务必检查其测试的操作系统和版本。如果您遇到问题,请发表评论,我们会尽力帮助。

如果您想要一个完全管理的体验,专门支持您可能想要运行的任何应用程序,请联系我们获取更多信息。

在我们最后的可以安全的教程中,我们介绍了Ansible的配置管理方法的基础知识,可以帮助您更快地设置新的服务器并提供更高的可靠性。我们在那里创建的可靠的手册是相当基本的,所以我认为是时候建立一个更复杂的手册,支持更多的安全性,而不是牺牲通过通常的方式访问服务器。

这个“安全”课程的目标是:

使用sudo访问设置非root用户。
升级所有安装的软件包
安装几个基本软件包,使初始管理更容易,如nano。这些可以根据您的需要轻松定制。
将您的SSH密钥复制到VPS以启用无密码登录。
硬化SSH具有一些基本的安全措施,例如禁用root和基于密码的登录。
iptables如果需要安装,并设置一些基本限制,以提高安全性。
安装fail2ban以防止暴力攻击。
最后两个步骤将在下周在本Ansys教程的第二部分中概述。

这个剧本不是全面的,当涉及到便利性或安全性 – 一旦你使用这个手册提供服务器,你应该可以研究一些额外的步骤,你可以采取,如使用Lynis审计您的安全。

这里的目标不仅仅是让您在此处复制代码并重新创建自己的手册 – 而是逐步介绍各种组件,以便您可以使用本手册作为自己的自定义设置的基础。

要求:

运行我们的任何操作系统选项的新配置或重建服务器 – CentOS,Debian或Ubuntu。
可以安装在本地机器上 – 有关详细信息,请参阅这些说明
使用您的服务器的IP设置的可安装主机文件 – 请参阅我们上一个教程的步骤2
步骤1.设置playbook结构

可以通过多种不同的方式构建可读的剧本,但是开发者们也有其建议。这个Anisble脚本与系统的可能性相比还是比较简单的,所以我们的结构也会变得简单得多。

以下是我们的一般结构:

provision.yml

roles
 common/
 tasks/
 main.yml
 ssh
 tasks/
 main.yml
 packages
 tasks/
 main.yml
 iptables
 tasks/
 main.yml

如果你愿意,你可以继续创建目录,只是为了让你更好地了解如何将其逻辑分为不同的区域。

步骤2.创建provisioning.yml

该provision.yml文件是我们的Playbook的核心 – 它是我们定义哪些服务器,我们将要使用的几个全局变量,并告诉可以在哪里查找其任务。

---
- name: Provision a new server with hardened SSH and basic iptables.

# Specify the hosts you want to target
 hosts: <b>HOST</b>

# Specify the user you want to connect to the server.
 # With a new installation, you will connect with `root`. If you want to
 # re-run this playbook at a later date, you should change `remote_user` to
 # the user you specified under `vars/username` below and uncomment the
 # `become: true` line. You should then run the playbook using the
 # `--ask-become-pass` flag, like so:
 # `ansible-playbook -k provision.yml --ask-become-pass`.
 remote_user: root
 # become: true

vars:
 username: <b>USER</b>
 # Before first using the playbook, run the below command to create a hashed
 # password that Ansible will assign to your new user.
 # python -c 'import crypt; print crypt.crypt("<b>password</b>", "$1$<b>SALT</b>$")'
 password: <b>PASSWORD GOES HERE</b>
 public_key: ~/.ssh/id_rsa.pub

roles:
 - user
 - packages
 - ssh
 - iptables

您需要根据需要更改许多变量。

步骤3.创建用户/任务/ main.yml

我们的第一个主要步骤是为新的非root用户设置正确的环境,然后创建该用户。这是第一个组件:

- name: Ensure wheel group is present
 group:
 name: wheel
 state: present

这个可执行的任务是一个简单的任务:它检查wheel您的服务器上是否存在该组。如果它不是由于某种原因 – 它应该在我们的所有操作系统选项上 – 剧本将失败,然后您可以用groupadd命令修复它。

下一步是关键的一步,所以让我们来看看:

- name: Ensure wheel group has sudo privileges
 lineinfile:
 dest: /etc/sudoers
 state: present
 regexp: "^%wheel"
 line: "%wheel ALL=(ALL:ALL) ALL"
 validate: "/usr/sbin/visudo -cf %s"

这是使用正则表达式替换文本中的一行与不同文本字符串的示例。我们正在查看/etc/sudoers文件内部,并请求开始(^)的行%wheel。当找到该行时,我们将整个行替换为%wheel ALL=(ALL:ALL) ALL允许wheel组中的用户执行命令sudo。在编辑方面/etc/sudoers,最后validate一行是至关重要的,因为您不喜欢由于不正确的文件而导致剧本失败而不是破坏管理员功能。

我们也想确保sudo软件包安装好了。

- name: Install the `sudo` package
 package:
 name: sudo
 state: latest

安装任何软件包,无论是CentOS,Ubuntu还是Debian,都以完全相同的方式运行。这就是Ansible的美丽 – 你可以创建一个任务,因为内置的逻辑工作。

最后,我们创建在其中的变量中指定的非root用户帐户provision.yml。

- name: Create the non-root user account
 user:
 name: ""
 password: ""
 shell: /bin/bash
 update_password: on_create
 groups: wheel
 append: yes

append: yes

此任务将使用您创建的散列密码设置用户,并将shell设置为/bin/bash。因为我们把这个用户放在wheel组里,我们可以直接使用sudo。

步骤4.创建packages / tasks / main.yml

该packages任务非常简单:我们只想更新所有软件包,以便我们拥有最新的安全修复程序,然后根据我们的具体需求安装多个额外的软件包。

- name: Upgrading all packages (Ubuntu/Debian)
 apt:
 upgrade: dist
 when: ansible_os_family == "Debian" or ansible_os_family == "Ubuntu"

- name: Upgrading all packages (CentOS)
 yum:
 name: '*'
 state: latest
 when: ansible_os_family == "RedHat"

这两个任务的关键是when选项 – 这允许您指定何时根据您选择的操作系统运行某些命令。这是必要的,因为yum在Ubuntu上不起作用,apt不能在CentOS上工作。在这两种情况下,我们只是要求相应的软件包管理器更新每个安装的软件包。

我们还可以安装其他软件包:

- name: Install a few more packages
 package:
 name: "{{item}}"
 state: installed
 with_items:
 - vim
 - htop

本质上,我们要求package任务查看下面的项目列表with_items,然后依次安装它们。如果您想要一些自己的软件包,只需将该列表自定义为您的内容。

步骤5.创建ssh / tasks / main.yml

接下来,我们要启用使用SSH密钥登录到新创建的用户,而不是密码 – 这是简单而有效的安全措施。除此之外,我们希望使用Ansible对SSH守护进程进行一些配置更改,这将使其不会受到一些基本攻击。这不是万无一失的,但它肯定是高于默认值的一大步。

- name: Add local public key for key-based SSH authentication
 authorized_key:
 user: ""
 state: present
 key: ""

此命令在本地机器上在该vars部分中指定的位置查找SSH密钥provision.yml,然后将其复制到服务器。比使用更容易ssh-copy-id吗?

接下来,让我们使SSH更安全一些。

- name: Harden sshd configuration
 lineinfile:
 dest: /etc/ssh/sshd_config
 regexp: "{{item.regexp}}"
 line: "{{item.line}}"
 state: present
 with_items:
 - regexp: "^#?PermitRootLogin"
 line: "PermitRootLogin no"
 - regexp: "^^#?PasswordAuthentication"
 line: "PasswordAuthentication no"
 - regexp: "^#?AllowAgentForwarding"
 line: "AllowAgentForwarding no"
 - regexp: "^#?AllowTcpForwarding"
 line: "AllowTcpForwarding no"
 - regexp: "^#?MaxAuthTries"
 line: "MaxAuthTries 2"
 - regexp: "^#?MaxSessions"
 line: "MaxSessions 2"
 - regexp: "^#?TCPKeepAlive"
 line: "TCPKeepAlive no"
 - regexp: "^#?UseDNS"
 line: "UseDNS no"
 - regexp: "^#?AllowAgentForwarding"
 line: "AllowAgentForwarding no"

在lineinfile和regexp应该熟悉你在这一点上,与在修改/etc/sudoers,我们正在寻找/etc/ssh/sshd_config和更换一批以新的现有生产线的。如果这些行当前不存在,则Ansible将在包含我们的修订版本的文件的底部创建新行。在^#?正则表达式使我们能够取代线是否他们注释掉,从而与一个开始#。

最后,让我们拥有SSD守护进程,以确保我们的更改已被应用。

- name: Restart sshd
 systemd:
 state: restarted
 daemon_reload: yes
 name: sshd

这个systemd任务允许我们运行相当于systemd restart sshd。

最后的想法

如上所述,我们在这里暂停一会儿,并将从本教程的下半部分返回一个星期,这将通过一个基本的iptables配置和安装fail2ban。

但是,在此期间,你现在可以运行这个剧本和更高版本。这是一个正确配置的可疑剧本的好东西 – 它们是幂等的,这意味着它们可以一次又一次地运行,而不会改变超出初始安装的结果。你可以运行一下这个playbook,做一个小小的变化,比如添加另外一个package来安装这个packages角色,然后再运行一下这个playbook,没有错误。

一旦你把所有的东西都运行起来,你如何实际运行这个剧本?这很简单

生成一个散列密码。您首先需要将非root用户所需的密码转换为散列密码。该命令应该在Linux和OS X上工作,并确保password用您选择的密码替换:python -c ‘import crypt; print crypt.crypt(“password”, “$1$AnsibleSalt$”)’。

复制你的新哈希provision.yml。

运行Ansible。通过一个简单的命令,运行本书本身就是直截了当的:$ ansible-playbook -k provision.yml

如果您需要在第一次运行后重新运行该手册,您需要对provision.yml上述代码(以及您创建的版本)进行一些更改,以获取一些基本说明。

请继续关注后期的教程,以及您需要在自己的服务器上运行此剧本的完整代码,并使之更快地工作。