ansible安全优化篇

一、安全概况

对与一台全新安装的服务器,尤其是直接面向公网的服务器来说:最重要的一项配置就是安全配置。

针对非授权连接和截取通信信息等攻击行为,避免攻击手段带来的危害,处理方法有以下方法:

  1. 使用安全加密的通信方式------使用https加密传输;
  2. 禁止root用户远程登录并充分利用sudo;
  3. 移除非必需的软件,只开发需要用到的端口;
  4. 遵守权限最小化原则;
  5. 及时更新操作系统和软件------修复旧版本的bug,并使用新版本的最佳性能;
  6. 使用合理配置过的、有针对性的防火墙;
  7. 确保日志文件被及时迁移、存放和切割;
  8. 监测系统登录情况,封掉可疑的IP地址;
  9. 正确使用SELinux和AppArmor。

二、SSH与远程连接简介

一、Telnet

Telnet协议诞生于20世纪60年代后期,最初被应用到基于TCP协议的大型私有网络之中,默认端口是23号端口。

Telnet是一种文本协议,用于在不同网络间传输数据。Telnet属于底层协议,至今它依然是我们现在使用的很多通信协议的基础,比如HTTP、FTP以及POP3。

随着SSH的到来,Telnet开始逐渐退出远程管理的舞台。

二、SSH

SSH(Secure Shell)诞生于1995年,由芬兰人Tatu Ylonen开发。他看到了文本通信的安全缺陷,这促使他开发一款强加密的远程管理工具------SSH。

SSH的连接加密方式非常类似于HTTP的SSL加密,同时SSH的认证层还增加了更高的安全机制。

三、通信加密

一、为了保证服务器的安全性,我们需要:

  1. 禁止SSH基于密码登录(禁止密码登录之前,务必确认SSH可以成功秘钥认证登录),使用更为安全的秘钥认证来加密通信
  2. 禁止root用户远程登录
  3. 同时改变SSH服务的默认端口号

二、实现功能

1、实现sshd_config.yml文件如下
复制代码
- hosts: example
    tasks:
        - name: 修改SSH配置文件的安全选项
            lineinfile:
            dest: /etc.ssh/sshd_config
            regexp: "{{ item.regexp }}"
            line: "{{ item.line }}"
            state: present
        with_items:
            - {
                regexp: "^PasswordAuthentication",
                line: "PasswordAuthentication no"
            }
            - {
                regexp: "^PermitRootLogin",
                line: "PermitRootLogin no"
            }
            - {
                regexp: "^Port",
                line: "Port 2849"
            }
        notify: restart ssh
    handlers:
        - name: restart ssh
            service: name=ssh state=restarted
2、实现方法

使用ansible的linefile模块对SSH的三大安全配置选项进行设置,随便使用handler了重启,来使修改生效。

3、需要注意的点

若改变了某些Inentory主机的SSH配置,比如更改了默认的端口号,此时我们需要在ansible的Inventory文件中使用ansible_ssh_port变量明确地为该主机重新指定新配置的端口号。

四、禁止root远程登录

使用lineinfile模块来配置SSH完全禁止使用root用户远程登录。

一、权限控制简介

Linux系统的sudo命令可以让普通用户以root(也可以指定为其他用户)的权限来执行指定命令,这样不仅减少了root用户和管理时间,同样也提高了安全性。sudo命令可以在执行敏感的高权限命令时,更加有针对性,从而减少高权限命令误操作的几率。

ansible本身也提倡尽量使用普通用户来管理主机,只有必须使用root权限的任务中,才使用sudo变量来实现Linux命令行中的sudo功能。

复制代码
---
    - name: Restart Apache.
        service: name=httpd state=restarted
        sudo: yes

在任务或playbook中可以通过添加sudo_user:[username]关键字来指定sudo后具体以哪个用户的权限来执行操作,而不仅仅是root用户。

需要注意的是:sudo_user关键字必须在有sudo关键字的前提下才生效。

二、ansible将普通用户提权

使用ansible修改sudo的配置文件,使普通用户拥有和root用户一样的权限。

1、实现方式一:使用lineinfile
复制代码
---
    - name: 为普通用户赋予所有root权限
        lineinfile:
            dest: /etc/sudoers
            regexp: '^%wzs'
            line: 'wzs ALL=(All) NOPASSWD: ALL'
            state: present

使用lininfile模块操作可能达不到预期的效果。所以使用这种方式时,应该认真检查,确保修改后语法的正确性。

更好的更改方式是远程执行visudo命令,更改sudo命令,并防止错误修改造成命令的不可用。

2、实现方式二:ansible主机修改sudo配置文件,使用visudo命令
复制代码
---

    - name: Copy validated sudoers file into place.
        copy:
            src: sudoers
            dest: /etc/sudoers
            validate: 'visudo -cf %s'

%s是一个文件路径的占位符,在文件被复制到远程主机之前,他会被替换为src后面的文件。

五、操作系统简介

一、未使用配置文件管理工具的痛点

在配置文件管理工具流行之前,服务器经常会残留一些不再使用的软件服务,以及这些服务所使用的端口。这不仅使服务器变得缓慢臃肿,同时这些开放的端口和老旧的软件都易受到外部攻击,造成潜在风险。

及时关闭服务器上不再需要的服务,卸载不相关的软件,并清理不再需要执行crontab任务,这不仅可以帮助服务器"瘦身",还可以提高服务器的安全性。

二、使用ansible配置管理

使用ansible来管理维护服务器架构,上面的痛点轻松解决。

1、解决方式:
  1. 使用事先写好的Playbook或Role快速地部署一台全新的服务器来取代旧服务器。
  2. 简单地列出一个需要删除的软件列表,利用ansible进行批量卸载。
2、使用ansible批量卸载不需要的软件
复制代码
---
    - name: 卸载不需要的软件
        yum: name={{ item }} state=absent purge=yes
        with_items:
            - apache2
            - nano
            - php

注意:state不同选项的区别

  1. present,installed是安装套件,而latest则是指安装最新的套件,也就是会使用 yum mirror 上最新的版本。
  2. absent, removed 是删除套件,没有什么区别
3、ansible批量操作
1、服务、文件

在ansible中,像yum、apt、file、mysql_db这些模块,他们都有一个相同的选项state,设置其值为absent,可以将指定的任务软件、文件或者数据库删除掉。妥善利用这些功能,可以大大提高运维人员的工作效率,节省大量时间。

2、端口

只开放需要用到的端口,关闭哪些可有可无的端口,将大大减少外部环境对主机的攻击面,同时也会降低防火墙的复杂度。

举例:不加任何限制就对外开放25端口会给外部网络提供大量的主机信息。所以。若你的主机不是一台SMTP服务器的话,务必关闭这个端口。同时,也要确保哪些需要被开启的端口,只能连接依赖的客户端。

六、遵守权限最小化原则

生产环境中,主机上的所有用户、应用以及进程都应该只允许访问他们本身需要访问的信息(文件)和资源(内存、网络等)------一点也不多,一点也不少

在权限最小化原则实施的过程中,最直接的也是最基本的两个方向:用户权限管理和文件权限管理。

一、用户管理

系统上的每一个新增用户的权限默认都是被适当限制过的。新增用户通常都有一个家目录,且用户对家目录下的所有文件和目录具有最搞权限,但是对于家目录以外的目录与文件的权限都需要重新赋予。

**  为用户新增权限的方法有两种**

  1. 添加用户到其他用户组中,已继承该用户组的权限
  2. 为用户开放sudo权限,使得其可以以root或者其他用户的身份来执行命令或者访问文件

二、文件权限管理

ansible中每一个与文件管理相关的模块中都有文件权限管理的选项可用,这些选项包括:owner、group和mode。每一次使用copy、template、file等模块来操作管理文件时,都应该使用这些选项来明确指定文件的权限及其归属。

1、实践:gitlab的配置文件应该只能被root用户读取和修改,其他任何用户都没有权限
复制代码
---
    - name: 设置gitlab配置文件的权限
        file:
            path: /etc/gitlab/gitlab.rb
            owner: root
            group: root
            mode: 0600
2、配置文件或者目录权限

为了满足用户对某些文件或目录的权限需求,正确的做法是修改文件或目录的权限来适应用户,而不是扩大用户权限来得到某些权限的满足。

例如:web服务器上httpd用户或者Nginx用户对网站文件拥有权限。

七、定期维护更新

服务器每一年所有软件的安全更新有上百次甚至更多。其中有一些是针对修复对系统有严重威胁的漏洞的,若这些漏洞没有及时更新软件或打相应的补丁,将会对系统安全造成严重威胁。

应该定期进行补丁维护和软件更新检查。在对线上生产服务器上的软件打补丁或者更新升级之前,应该在非关键服务器或环境相同的测试服务器上进行测试,在确定没问题的情况下再对线上生产服务器进行操作。

一、手动更新

使用ansible命令对服务器上所有软件更新升级操作。

然而,在有些情况下我们只需实施与安全相关的更新,或者只更新某些软件;在仍需要使用这两个命令的前提下,可以通过修改yum软件和apt软件的配置文件来进行定义。

1、对于RedHat和CentOS等系统来说,使用如下命令
复制代码
ansible webservers -m yum -a "name=* state=latest"
2、对于Debian和Ubuntu等系统来说,使用如下命令
复制代码
ansible webservers -m apt -a "upgrade=dist update_cache=yes"

二、自动定时更新

可以在系统上设置每天或每周定时进行软件更新,这样可以使系统更新这一动作更稳定、更有规律地执行下去,从而减少人力成本。

但在现实中,有些环境是不允许机器自动更新软件的,因为自动更新本身蕴含着一些风险。比如:有些软件的最新版确实修正了之前版本的一些不足,但是它的新增功能可能与系统上自己开发的一些程序的兼容性不足,从而使得整个系统不可用。

若你的系统上不存在这些问题,那么使用自动定时更新软件,可以更进一步增加系统安全性。

1、自动更新RedHat系统上的软件

对于RedHat 6及其以后的版本的系统(包括Fedora和CentOS)都可以使用一个叫YUM-cron的软件进行软件包更新管理。其用法很简单,使用yum安全后,保证开机开启就可以了。使用ansible来实现如下即可

复制代码
---
    - name: 安装yum-cron
        yum: name=yum-cron state=present
    
    - name: 运行yum-cron并设置开机启动
        services: name=yum-cron state=started enabled=yes

更多的配置可以通过修改yum的配置文件/etc/yum.conf

2、自动更新Debian系统上的软件

Debian系统及其衍生版都使用一款名叫unattended-upgrades的软件来实现自动化软件包更新管理,这款软件和前面讲的YUM-cron一样,非常便于安装和配置,并且支持多配置文件,存放于/etc/apt/apt.conf.d/。

复制代码
---
    - name: 安装unattended-upgrades
        apt: name=unattended-upgrades state=present

    - name: 将配置文件复制到配置目录中
        template:
            src: "../templates/{{ item }}.j2"
            dest: "/etc/apt/apt.conf.d/{{ item }}"
            owner: root
            group: root
            mode: 0644
        with_items:
            - 10periodic
            - 50unattended-upgrades

复制unattended-upgrades配置文件中10periodic的内容如下

复制代码
APT::Periodic::Update-Package-Lists "1";            //显示更新包列表,0表示停用设置
APT::Periodic::Download-Upgradeable-Packages  "1";  //下载更新包,0表示停用设置
APT::Periodic::AutocleanInterval "7";               //7天自动删除
APT::Periodic::Unattended-Upgrade "1";              //启动自动更新,0表示停用自动更新

配置文件50unattended-upgrades的内容如下

复制代码
Unattended-Upgrade::Automatic-Reboot "false";

Unattended-Upgrade::Allowed-Origins {
    "Ubuntu lucid-security";
    "Ubuntu lucid-updates; 
};

这个配置文件提供了更新配置选项,比如对于那些更新后需要重启服务器才能生效的软件,在更新过这些软件后,是否自动重启服务器,以及在检查更新软件,需要检测那些APT源来查找更新等。

八、iptables防火墙

管理防火墙的工具,比如iptables、ufw以及firewalld等。

一、在Debian及衍生系统,ansible的ufw模块来完成

使用ansible开关闭Debian系统中除了22(SSH)、80(HTTP)、123(NTP)端口以外的其他的所有端口。

1、代码实现
复制代码
---
    - name: 使用ufw模块来管理那些端口需要开启
        ufw:
            rule: "{{ item.rule }}"
            port: "{{ item.port }}"
            proto: "{{ item.proto }}"
        with_item:
            - { rule: 'allow', port: 22, proto: 'tcp' }
            - { rule: 'allow', port: 80, proto: 'tcp' }
            - { rule: 'allow', port: 123, proto: 'ucp' }
    - name: 配置网络进出方向的默认规则
        ufw:
            direction: "{{ item.direction }}"
            policy: "{{ item.policy }}"
            state: enabled
        with_items:
            - { direction: outgoing, policy: allow }
            - { direction: incoming, policy: deny }
2、上面playbook任务运行之后,登录对方主机,使用sudo ufw status verbose命令

二、在RedHat及其衍生系统中,我们使用ansible的firewalld模块来管理防火墙

1、代码实现
复制代码
---
    - name: 使用firewalld模块管理端口
        firewalled:
            state: "{{ item.state }}"
            port: "{{ item.port }}"
            zone: external
            immediate: yes
            permanent: yes
        with_items:
            - { state: 'enabled', port: '22/tcp' }
            - { state: 'enabled', port: '80/tcp' }
            - { state: 'enabled', port: '123/ucp' }

注意:

1、immediate选项从ansible版本1.9之外开始引入,用来定义规则在配置完成是否立即生效。若使用的是1.9之前的版本的,那么需要重启防火墙来让新规则生效,或者将permanent选项的值设为no。

2、firewalld模块并不能针对网络进出口方向进行管理,但是我们可以借助iptables模块或者直接修改/etc/firewalld目录下的防火墙配置文件来进行配置。

2、查看被放行的端口
复制代码
sudo firewall-cmd --zone=external --list-all
相关推荐
网安小白的进阶之路1 小时前
A模块 系统与网络安全 第三门课 网络通信原理-3
网络·windows·安全·web安全·系统安全
HumanRisk2 小时前
HumanRisk-自动化安全意识与合规教育平台方案
网络·安全·web安全·网络安全意识教育
安全系统学习9 小时前
【网络安全】Mysql注入中锁机制
安全·web安全·网络安全·渗透测试·xss
风清再凯12 小时前
自动化工具ansible,以及playbook剧本
运维·自动化·ansible
深圳安锐科技有限公司12 小时前
深圳安锐科技发布国内首款4G 索力仪!让斜拉桥索力自动化监测更精准高效
运维·安全·自动化·自动化监测·人工监测·桥梁监测·索力监测
IT乌鸦坐飞机12 小时前
ansible部署数据库服务随机启动并创建用户和设置用户有完全权限
数据库·ansible·centos7
潘锦13 小时前
海量「免费」的 OPENAI KEY,你敢用吗?
安全·openai
冰橙子id13 小时前
linux系统安全
linux·安全·系统安全
上海锝秉工控14 小时前
防爆拉线位移传感器:工业安全的“隐形守护者”
大数据·人工智能·安全
你不知道我是谁?16 小时前
AI 应用于进攻性安全
人工智能·安全