使用Ansible Galaxy实现安全无忧的自动化部署

本文详细介绍了如何利用Ansible Galaxy角色自动化部署SSH安全配置、防火墙规则、fail2ban防护和日志收集系统,实现Linux服务器的快速安全加固,确保系统安全性和可重复性部署。

使用Ansible Galaxy实现安全无忧的自动化部署

作者:Jordan Drysdale
发布时间:2016年7月11日

注意: 本博文中引用的技术和工具可能已过时,不适用于当前情况。然而,这篇博文仍可作为学习机会,并可能更新或集成到现代工具和技术中。

作为一名“蓝队成员”,工作往往充满压力。在具有强大Linux基础设施的环境中工作可能会有所帮助,但Ansible可以极大地提升效率。在所有环境中,无论操作系统如何,我们都需要确保系统的远程访问安全。Ansible Galaxy充满了有趣的角色,可以让蓝队成员的生活更轻松。通过Ansible Galaxy,我们可以利用几个角色快速、有效地保护Linux服务器,并且易于复制。

在保护远程访问时,基于密钥的SSH和有时使用的双因素认证(2FA)可以提供额外的安全层。此外,很难想象放弃防御而“裸奔”,因此防火墙是标准要求。为什么不加入fail2ban来防御通过iptables攻击开放服务的尝试?我非常喜欢这种服务组合。🙂 “哦,你尝试了三次通过HTTPS进行认证?fail2ban,请暂时封锁这个IP。谢谢,好的。”最后但同样重要的是,让我们将所有内容转储到logstash中,在Kibana中进行Geo-IP映射以实现出色的可视化,最终可以安心休息。

首先,检查我们的Ansible版本:

1
2
3
ansible@tw17ch01:/etc/ansible/roles/sshd$ dpkg -l |grep ansible
ii  ansible   2.1.0.0-1ppa~trusty        all        
一个极其简单的IT自动化平台

接下来,安装、配置和部署SSHd,使用一个包含所有可能变量的Galaxy角色。我们将添加角色,进行一些更改,然后构建一个playbook来部署新角色。链接在此 – https://galaxy.ansible.com/mattwillsher/sshd/

Ansible服务器魔法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
ansible@tw17ch01:/etc/ansible/playbooks$ sudo ansible-galaxy install mattwillsher.sshd

[sudo]
 password for ansible:
– downloading role 'sshd', owned by mattwillsher
– downloading role from https://github.com/willshersystems/ansible-sshd/archive/v0.4.4.tar.gz
– extracting mattwillsher.sshd to /etc/ansible/roles/mattwillsher.sshd
– mattwillsher.sshd was installed successfully

ansible@tw17ch01:/etc/ansible/playbooks$ sudo mv mattwillsher.sshd/sshd/

Galaxy角色大部分在其“角色目录”中创建标准结构,如果不存在,

1
2
3
4
5
ansible@tw17ch01:/etc/ansible/roles/sshd$ ls

defaults   handlers  meta  tasks  tests  vars

ansible@tw17ch01:/etc/ansible/roles$ sudo nano sshd/vars/Ubuntu_14.yml

*强烈建议修改默认端口,完全禁用root登录,并添加一行PasswordAuthentication no。确保修改的文件适用于部署角色的操作系统。

接下来,安装、配置和部署防火墙以阻止所有内容。链接在此 – https://galaxy.ansible.com/geerlingguy/firewall/

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
ansible@tw17ch01:/etc/ansible/roles$ sudo ansible-galaxy install geerlingguy.firewall

[sudo]
 password for ansible:
– downloading role 'firewall', owned by geerlingguy
– downloading role from https://github.com/geerlingguy/ansible-role-firewall/archive/1.0.9.tar.gz
– extracting geerlingguy.firewall to /etc/ansible/roles/geerlingguy.firewall
– geerlingguy.firewall was installed successfully

ansible@tw17ch01:/etc/ansible/roles$ sudo mv geerlingguy.firewall/ chains/

让我们做一些编辑。

1
ansible@tw17ch01:/etc/ansible/roles$ sudo nano chains/defaults/main.yml

防火墙修改比sshd角色内置的复杂性更容易理解。我的系统只需要上述列出的SSH端口和HTTPS。对chains角色的另一个修改:

1
ansible@tw17ch01:/etc/ansible/roles$ sudo nano chains/templates/firewall.bash.j2

我添加了以下规则,因为我现在不关心来自DO droplet的出站流量。

1
2
3
#  允许所有出站流量 - 
#  您可以/应该修改此规则以仅允许特定流量!
iptables -A OUTPUT -j ACCEPT

chains角色应该准备好了。

接下来,安装、配置和部署fail2ban以保护服务。链接在此 – https://galaxy.ansible.com/tersmitten/fail2ban/

1
2
3
4
5
6
7
ansible@tw17ch01:/etc/ansible/roles$ sudo ansible-galaxy install tersmitten.fail2ban
- downloading role 'fail2ban', owned by tersmitten
- downloading role from https://github.com/Oefenweb/ansible-fail2ban/archive/v1.5.0.tar.gz
- extracting tersmitten.fail2ban to /etc/ansible/roles/tersmitten.fail2ban
- tersmitten.fail2ban was installed successfully

ansible@tw17ch01:/etc/ansible/roles$ sudo mv tersmitten.fail2ban/ banner/

让我们做一些编辑

1
ansible@tw17ch01:/etc/ansible/roles$ sudo nano banner/defaults/main.yml

我必须对我的sshd服务配置进行一些更改,以反映使用非标准端口的情况。我还添加了HTTPS的服务配置。在查看目录结构的其余部分后,这个角色也准备好了。

最后,安装、配置和部署filebeat以将日志文件发送到有用的目的地。链接在此 – https://galaxy.ansible.com/jpnewman/elk-filebeat/

1
2
3
4
5
6
7
ansible@tw17ch01:/etc/ansible/roles$ sudo ansible-galaxy install jpnewman.elk-filebeat
- downloading role 'elk-filebeat', owned by jpnewman
- downloading role from https://github.com/jpnewman/ansible-role-elk-filebeat/archive/master.tar.gz
- extracting jpnewman.elk-filebeat to /etc/ansible/roles/jpnewman.elk-filebeat
- jpnewman.elk-filebeat was installed successfully

ansible@tw17ch01:/etc/ansible/roles$ sudo mv jpnewman.elk-filebeat/ logger/

最后,让我们设置TLS日志传输,以便在现有ELK堆栈中进行未来勘探。这假设已经完成了一系列工作:

  1. 完全可操作的ELK堆栈
  2. 为logstash部署的TLS/PKI基础设施和证书可通过logger角色部署
  3. 网络防火墙上的logstash端口转发
  4. 可选的redis集群处理大量日志处理
1
ansible@tw17ch01:/etc/ansible/roles$ sudo nano logger/defaults/main.yml

在这里,我修改了elastic和logstash主机以指向基础设施目的地。还记得我们之前讨论过的相当标准的目录结构吗?是的,将您的logstash-forward.crt文件复制到../roles/logger/files/certs/中,playbook智能将交付。我们又准备好了。让我们开始并检查一些事情以确保一切正常。

1
2
3
4
ansible@tw17ch01:/etc/ansible/roles$ ls
banner  chains  logger  sshd   ### 所有角色都存在
gt; vi ../ansible/hosts #将新主机添加到您的ansible hosts文件中
gt; ansible dropper ping -m 12.34.56.78 | SUCCESS => {         "changed": false,         "ping": "pong" } ansible@tw17ch01:/etc/ansible/roles$ sudo nano ../playbooks/NewDrop.yml ### 角色很棒。投入时间。 - hosts: all   become: yes   roles:         # 部署标准SSH配置         - { role: sshd }         # 安装iptables         - { role: chains }         # 添加filebeat         - { role: logger }         # 部署和配置fail2ban         - { role: banner }  

此部署的手动部分在此处发生。SSH到新的droplet并创建一个sudo用户。是的,这可以自动化,我们将在另一天以另一种方式写关于此的内容。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
ssh root@NewDropIP
useradd ansible -m -s /bin/bash
passwd ansible
UNIX Pass:
UNIX Pass:
su - ansible
mkdir .ssh
touch .ssh/authorized_keys
echo "ssh-rsa AAAAB3N <KEY REDACTED> IClTJ1E1 ansible@tw17ch01" >> .ssh/authorized_keys
exit
visudo   ## 添加 ansible ALL=(ALL:ALL) ALL

ansible@tw17ch01:/etc/ansible$ sudo nano hosts  ### 添加 [dropper] 和 NewDropIP
ansible@tw17ch01:/etc/ansible$
ansible@tw17ch01:/etc/ansible$ ansible-playbook playbooks/NewDrop.yml -l dropper -u ansible -K
SUDO password:

PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
The authenticity of host '12.34.56.78 (12.34.56.78)' can't be established.
ECDSA key fingerprint is 5f:<redacted>:1f.
Are you sure you want to continue connecting (yes/no)? yes
Enter passphrase for key '/home/ansible/.ssh/id_rsa':
ok: [12.34.56.78]
TASK [sshd : Set OS dependent variables] ***************************************
ok: [12.34.56.78] => (item=/etc/ansible/roles/sshd/vars/Ubuntu_14.yml)
TASK [sshd : OS is supported] **************************************************
ok: [12.34.56.78]
TASK [sshd : Installed] ********************************************************
ok: [12.34.56.78] => (item=[u'openssh-server', u'openssh-sftp-server'])
TASK [sshd : Run directory] ****************************************************
ok: [12.34.56.78]
TASK [sshd : Configuration] ****************************************************
changed: [12.34.56.78]
TASK [sshd : Service enabled and running] **************************************
ok: [12.34.56.78]
TASK [sshd : Register that this role has run] **********************************
ok: [12.34.56.78]
TASK [chains : Ensure iptables is installed (RedHat).] *************************
skipping: [12.34.56.78]
TASK [chains : Ensure iptables is installed (Debian).] *************************
ok: [12.34.56.78]
TASK [chains : Flush iptables the first time playbook runs.] *******************
changed: [12.34.56.78]
TASK [chains : Copy firewall script into place.] *******************************
changed: [12.34.56.78]
TASK [chains : Copy firewall init script into place.] **************************
changed: [12.34.56.78]
TASK [chains : Ensure the firewall is enabled and will start on boot.] *********
changed: [12.34.56.78]
TASK [logger : Create directory to store ssl crt] ******************************
changed: [12.34.56.78]
TASK [logger : Copy SSL cert] **************************************************
changed: [12.34.56.78]
TASK [logger : Install Filebeat dependencies] **********************************
ok: [12.34.56.78]
TASK [logger : Check if Filebeat is already at the right version] **************
changed: [12.34.56.78]
TASK [logger : Download Filebeat agent] ****************************************
changed: [12.34.56.78]
TASK [logger : Install Filebeat agent] *****************************************
changed: [12.34.56.78]
TASK [logger : Create directory for Filebeat Configures] ***********************
changed: [12.34.56.78]
TASK [logger : Create directory for Filebeat Configures] ***********************
changed: [12.34.56.78]
TASK [logger : Configure Filebeat] *********************************************
changed: [12.34.56.78]
TASK [logger : Configure Filebeat prospectors] *********************************
[DEPRECATION WARNING]: Using bare variables is deprecated. Update your playbooks  ### 需要清理此playbook
 so that the environment value uses the full variable syntax
('{{prospectors}}').
This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
changed: [12.34.56.78] => (item={u'paths': [{u'log_paths': [u'/var/log/syslog', u'/var/log/auth.log'], u'document_type': u'syslog'}], u'type': u'syslog', u'id': u'syslog'})
changed: [12.34.56.78] => (item={u'paths': [{u'log_paths': [u'/var/log/*.log'], u'document_type': u'log', u'exclude_files': [u'^syslog

太棒了!我们刚刚推出了解决我(或大多数管理员)担心的几乎所有问题的解决方案。让我们通过SSH查看一下,确保没有出现问题,并验证一切正常。

SSH:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
ansible@tw17ch03:~$ cat /etc/ssh/sshd_config
# ansible managed: /etc/ansible/roles/sshd/templates/sshd_config.j2 modified on 2016-04-16 12:32:30 by root on tw17ch01
Port 22444
Protocol 2
HostKey /etc/ssh/ssh_host_rsa_key
AcceptEnv LANG LC_*
ChallengeResponseAuthentication no
HostbasedAuthentication no
IgnoreRhosts yes
KeyRegenerationInterval 3600
LogLevel INFO
LoginGraceTime 120
PasswordAuthentication no
[...............]
X11Forwarding yes

iptables:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
ansible@tw17ch03:~$ sudo iptables -L

[sudo]
 password for tendans:
Chain INPUT (policy ACCEPT)

target         prot opt source                 destination         
ACCEPT         all  —  anywhere               anywhere            
ACCEPT         tcp  —  anywhere               anywhere            tcp dpt:22444
ACCEPT         tcp  —  anywhere               anywhere            tcp dpt:https
ACCEPT         icmp —  anywhere               anywhere            
ACCEPT         udp  —  anywhere               anywhere            udp spt:ntp
ACCEPT         all  —  anywhere               anywhere            state RELATED,ESTABLISHED
LOG            all  —  anywhere               anywhere            limit: avg 15/min burst 5 LOG level debug prefix “Dropped by firewall: ”
DROP           all  —  anywhere               anywhere            

Chain FORWARD (policy ACCEPT)
target         prot opt source                 destination         
Chain OUTPUT (policy ACCEPT)
target         prot opt source                 destination         
ACCEPT         all  —  anywhere               anywhere            
ACCEPT         udp  —  anywhere               anywhere            udp dpt:ntp

FileBeat:

1
2
3
4
5
6
ansible@tw17ch03:~$ cat /etc/filebeat/filebeat.yml

################### Filebeat Configuration Example #########################
############################# Filebeat ######################################
filebeat:
# List of prospectors to fetch data.

Fail2Ban:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
tendans@tw17ch03:~$ cat /etc/fail2ban/jail.local
# ansible managed: /etc/ansible/roles/banner/templates/etc/fail2ban/jail.local.j2 modified on 2016-05-30 05:57:15 by root on tw17ch01
[……]


[ssh]

enabled = true
port = 22444
filter = sshd
logpath = /var/log/auth.log
maxretry = 6
findtime = 600

[https]

enabled = true
port = https
filter = https
logpath = /var/log/auth.log
maxretry = 6
findtime = 600

就是这样,全部完成了。Playbook看起来很好,所有角色都按预期部署。配置文件已更新,SSH允许我们远程访问。哦,对了,这里有一个Kibana可视化,显示了通过FileBeat打包日志传输的远程连接的源Geo-IP映射,并向一位未具名的同事致敬,干杯!

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计