Ansible实现等保安全合规基线,运维尽力了!

需求

《结合等级保护了解服务器合规基线配置》一文从普法的角度给逐级介绍了等级保护级别、安全通用要求、安全计算环境。由于我们基础设施都在安全计算环境中,因此需要我们关注的安全控制点为:

  • 身份鉴别
  • 访问控制
  • 安全审计
  • 入侵防范
  • 恶意代码防范
  • 可信验证
  • 数据完整性
  • 数据保密性
  • 数据备份与恢复
  • 剩余信息保护

既然安全控制点已经找到,那么我们就可以根据其进一步的要求由点及面来详细展开了。

解决方案

对于安全合规基线,我们肯定希望能够对所有纳管的服务器进行批量更新,最好还可以根据最新的标准不断进行持续优化更新。因此我们使用Ansible Playbook进行统一管理,一方面安全合规基线配置是系统标准初始化的一部分,另一方面其也可以对基线进行单独的执行。

我们利用ansible playbook的tag功能以及gather_facts获取操作系统版本,下面是我们全部操作系统初始化的task:

vim /ansible/ansible-playbook/roles/os_init/task/main.yml
- include: hostname.yml  #主机名管理
- include: user.yml  #用户管理
- include: repo.yml  #yum源
- include: init_pkg.yml  #安装基础组件
- include: profile.yml  #环境变量
- include: selinux.yml  #selinux
- include: dir.yml  #基础目录
- include: limits.yml   #系统参数
- include: iptables.yml  #防火墙
- include: sysctl.yml   #内核参数
- include: rc.local.yml   #开机启动
- include: dns.yml    #dns
- include: ntp.yml    #ntp
- include: rsyslog.yml  #日志同步
- include: sshd.yml  #ssh优化
- include: safe.yml   #安全基线配置
- include: audit.yml  #安全审计
复制代码

我们完整的合规基线由基础安全基线和其他不同组件的配置组成:

- include: profile.yml  #环境变量
- include: selinux.yml  #selinux
- include: rsyslog.yml  #日志同步
- include: sshd.yml  #ssh优化
- include: safe.yml   #基础安全合规基线
- include: audit.yml  #安全审计
复制代码

注意:为兼容Centos6和Centos7,我们在playbook中需要开启gather_facts获取操作系统版本,以便区分不同的配置操作。

对不同需求的合规配置,我们只需执行以下操作:

#操作系统全部初始化
ansible-playbook -b -e host_ip=10.10.2.10 -v os_init.yml
#通过tag实现安全审计
ansible-playbook -b -e host_ip=10.10.2.10 -v os_init.yml -t audit
#通过tag实现基础合规基线
ansible-playbook -b -e host_ip=10.10.2.10 -v os_init.yml -t safe
复制代码

具体实现

等保三级的合规基线要求非常严格,对于生产环境我们无法保证完全按其要求实施,因此本次Ansible具体实现我们是做了一定程度妥协的。如有需要,可以按此配置自行添加。

1.身份鉴别

1.应对登录的用户进行身份标识和鉴别,身份标识具有唯一性,应实现身份鉴别信息防窃取和防重用。静态口令应在8位以上,由字母、数字、符号等混合组成并每半年更换口令,不允许新设定的口令与前次旧口令相同。应用系统用户口令应在满足口令复杂度要求的基础上定期更换。

我们针对此项标准具体限制如下:

  • 密码过期时间(90天过期、长度最小8位、禁止使用重复密码)
  • 密码最小长度8位,复杂度包含大小写字母、数字、特殊字符,适配Centos6、Centos7
  • 密码登录尝试3次
  • 禁止旧密码
vim safe.yml
# 设置密码过期时间
- name: set password expire
  lineinfile:
    path: /etc/login.defs
    regexp: "{{ item.regexp_string }}"
    line: "{{ item.rule }}"
  with_items:
    - { regexp_string: "^PASS_MAX_DAYS", rule: "PASS_MAX_DAYS   90"}
    - { regexp_string: "^PASS_MIN_DAYS", rule: "PASS_MIN_DAYS   0"}
    - { regexp_string: "^PASS_MIN_LEN", rule: "PASS_MIN_LEN   8"}
    - { regexp_string: "^PASS_WARN_AGE", rule: "PASS_WARN_AGE   10"}
  tags: safe

# Centos7设置密码复杂度、长度
- name: 1.Centos7 set password quality  
  lineinfile:
    path: /etc/security/pwquality.conf
    regexp: "{{ item.regexp_string }}"
    line: "{{ item.rule }}"
  with_items:
    - { regexp_string: "minlen", rule: "minlen = 8"}
    - { regexp_string: "dcredit", rule: "dcredit = -1"}
    - { regexp_string: "lcredit", rule: "lcredit = -1"}
    - { regexp_string: "ocredit", rule: "ocredit = -1"}
    - { regexp_string: "ucredit", rule: "ucredit = -1"}
  when: ansible_distribution_major_version == "7"
  tags: safe

# 设置密码尝试3次
- name: 2.Centos7 set password quality  
  lineinfile:
    path: "{{ item }}"
    regexp: "^password    requisite     pam_pwquality.so"
    line: "password    requisite     pam_pwquality.so try_first_pass retry=3"
  with_items:
    - /etc/pam.d/password-auth
    - /etc/pam.d/system-auth
  when: ansible_distribution_major_version == "7"
  tags: safe

# Centos6设置密码尝试次数、复杂度、长度
- name: set password quality  
  lineinfile:
    path: "{{ item }}"
    regexp: "^password    requisite     pam_cracklib.so"
    line: "password    requisite     pam_cracklib.so try_first_pass retry=3  dcredit=-1 ucredit=-1 ocredit=-1 lcredit=0 minlen=8"
  with_items:
    - /etc/pam.d/password-auth
    - /etc/pam.d/system-auth
  when: ansible_distribution_major_version == "6"
  tags: safe

# 禁止重复使用旧密码
- name: set password quality  
  lineinfile:
    path: "{{ item }}"
    regexp: "^password    sufficient    pam_unix.so"
    line: "password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok remember=5"
  with_items:
    - /etc/pam.d/password-auth
    - /etc/pam.d/system-auth
  tags: safe
复制代码

2.应具有登录失败处理功能,应配置并启用结束会话、限制登录间隔、限制非法登录次数和当登录连接超时自动退出等相关措施。 我们针对此项标准具体限制如下:

  • 防暴力破解
  • 登录失败锁定(3次输入错误,锁定60秒)
  • 终端1800秒结束会话
  • ssh每次登录时间不大于一分钟
  • ssh身份验证尝试次数不大于4次
vim safe.yml
# 防暴力破解,共3步
- name: 1.prevent brute force
  lineinfile:
    path: "{{ item }}"
    insertafter: "auth        required      pam_env.so"
    line: "auth required pam_faillock.so preauth audit silent deny=3 unlock_time=60"
  with_items:
    - /etc/pam.d/password-auth
    - /etc/pam.d/system-auth
  tags: safe

- name: 2.prevent brute force
  lineinfile:
    path: "{{ item }}"
    insertafter: "auth        sufficient    pam_unix.so nullok try_first_pass"
    line: "auth [default=die] pam_faillock.so authfail audit deny=3 unlock_time=60"
  with_items:
    - /etc/pam.d/password-auth
    - /etc/pam.d/system-auth
  tags: safe

- name: 3.prevent brute force
  lineinfile:
    path: "{{ item }}"
    insertafter: "account     required      pam_unix.so"
    line: "account required pam_faillock.so"
  with_items:
    - /etc/pam.d/password-auth
    - /etc/pam.d/system-auth
  tags: safe
  
  
vim profile.yml
- name: /etc/profile
  lineinfile: 
    path: /etc/profile
    line: "{{ item }}"
  with_items:
    - "readonly TMOUT=1800"
    - 'export HISTTIMEFORMAT="%F %T # "'
    - "export HISTSIZE=10240"
    - "export PROMPT_COMMAND=\'{ msg=$(history 1 | { read x y; echo $y; });logger -p local3.notice \"[euid=$(whoami)]\":$(who am i):[`pwd`]\"$msg\"; }\'"
    - 'readonly PROMPT_COMMAND'
    
    
vim sshd.yml
- name: set sshd_config
  replace: path=/etc/ssh/sshd_config regexp={{ item.regexp }} replace={{ item.replace }}
  with_items:
    - { regexp: "#Port 22", replace: "Port 10022" }
    - { regexp: "#UseDNS yes", replace: "UseDNS no" }
    - { regexp: "#PermitRootLogin yes", replace: "PermitRootLogin no" }
    - { regexp: "GSSAPIAuthentication yes", replace: "GSSAPIAuthentication no" }
    - { regexp: "#PermitEmptyPasswords no", replace: "PermitEmptyPasswords no" }
    - { regexp: "#MaxAuthTries 6", replace: "MaxAuthTries 4" }
    - { regexp: "#LoginGraceTime 2m", replace: "LoginGraceTime 60" }
  notify: restart sshd
  tags: ssh

- name: restart sshd
  service: enabled=true name=sshd state=restarted
  tags: ssh
复制代码

3.应采用口令、密码技术、生物技术等两种或两种以上组合的鉴别技术对用户进行身份鉴别,且其中一种鉴别技术至少应使用密码技术来实现

对于服务器的远程登录,我们可以通过开源堡垒机或采购企业级堡垒机,堡垒机一般都支持密码、密钥、口令等多种认证方式,因此在此我们就不做进一步介绍了。

2.访问控制

1.应对登录的用户分配账户和权限。 2.应重命名或删除默认账户,修改默认账户或预设账户的默认口令。 4.应用系统应对首次登录的用户提示修改默认账户或预设账户的默认口令。 4.应及时删除或停用多余的、过期的账户,避免共享账户的存在。 5.应授予管理用户所需的最小权限,实现管理用户的权限分离。 6.应严格限制默认账户或预设账户的权限,如默认账户和预设账户的权限应为空权限或某单一功能专用权限等。 7.应由授权主体配置访问控制策略,访问控制策略规定主体对客体的访问规则。 8.访问控制的粒度应达到主体为用户级或进程级,客体为文件、数据库表级。 9.应对重要主体和客体设置安全标记,并控制主体对有安全标记信息资源的访问

访问控制涉及的账号分配、权限隔离等要求,基本上都和管理标准、制度有关,我们无法在自动化配置层面做太多的工作。

3.安全审计

1.应启用安全审计功能,审计覆盖到每个用户,对重要的用户行为和重要安全事件进行审计。 2.审计记录应包括事件的日期和时间、用户、事件类型、事件是否成功及其他与审计相关的信息。 3.应对审计记录进行保护,定期备份,避免受到未预期的删除、修改或覆盖等,审计记录保存时间应不少于6个月。 4.应对审计进程进行保护,防止未经授权的中断。 5.对于从互联网客户端登录的应用系统,应在用户登录时提供用户上一次非常用设备成功登录的日期、时间、方法、位置等信息。 6.审计记录产生时的时间应由系统范围内唯一确定的时钟产生,以确保审计分析的一致性与正确性。

我们针对此项标准具体限制如下:

  • 收集修改系统强制访问控制的事件
  • 收集系统网络环境修改事件
  • user/group 修改信息事件被收集
  • 收集用户删除文件事件
  • 收集内核模块的加载和卸载
  • 收集登陆登出事件
  • 收集会话启动事件
  • 保收集了成功的文件系统挂载
  • 收集系统管理员操作(sudolog)
  • 收集系统管理范围内的更改
  • 收集任意访问控制权限修改事件
  • 收集修改日期和时间信息的事件
vim audit.yml
- name: modify auditd.conf
  replace:
    path: /etc/audit/auditd.conf
    regexp: 'max_log_file_action = ROTATE'
    replace: 'max_log_file_action = keep_logs'
  notify: restart auditd
  tags: audit 

- name: add audit.rules
  lineinfile: 
    path: /etc/audit/rules.d/audit.rules
    line: "{{ item }}"
  with_items:
    - "#确保收集了修改系统强制访问控制的事件"
    - "-w /etc/selinux/ -p wa -k MAC-policy"
    - "-w /usr/share/selinux/ -p wa -k MAC-policy"
    - "#确保收集了系统网络环境修改事件"
    - "-a always,exit -F arch=b64 -S sethostname -S setdomainname -k system-locale"
    - "-a always,exit -F arch=b32 -S sethostname -S setdomainname -k system-locale"
    - "-w /etc/issue -p wa -k system-locale"
    - "-w /etc/issue.net -p wa -k system-locale"
    - "-w /etc/hosts -p wa -k system-locale"
    - "-w /etc/sysconfig/network -p wa -k system-locale"
    - "-w /etc/sysconfig/network-scripts/ -p wa -k system-locale"
    - "#确保 user/group 修改信息事件被收集"
    - "-w /etc/group -p wa -k identity"
    - "-w /etc/passwd -p wa -k identity"
    - "-w /etc/gshadow -p wa -k identity"
    - "-w /etc/shadow -p wa -k identity"
    - "-w /etc/security/opasswd -p wa -k identity"
    - "#确保收集了用户删除文件事件"
    - "-a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete"
    - "-a always,exit -F arch=b32 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete"
    - "#确保收集了内核模块的加载和卸载"
    - "-w /sbin/insmod -p x -k modules"
    - "-w /sbin/rmmod -p x -k modules"
    - "-w /sbin/modprobe -p x -k modules"
    - "-a always,exit -F arch=b64 -S init_module -S delete_module -k modules"
    - "#确保收集了登陆登出事件"
    - "-w /var/log/lastlog -p wa -k logins"
    - "-w /var/run/faillock/ -p wa -k logins"
    - "#确保收集了会话启动事件"
    - "-w /var/run/utmp -p wa -k session"
    - "-w /var/log/wtmp -p wa -k logins"
    - "-w /var/log/btmp -p wa -k logins"
    - "#确保收集了成功的文件系统挂载"
    - "-a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts"
    - "-a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts"
    - "#确保收集了系统管理员操作(sudolog)"
    - "-w /var/log/sudo.log -p wa -k actions"
    - "#确保收集了系统管理范围内的更改"
    - "-w /etc/sudoers -p wa -k scope"
    - "-w /etc/sudoers.d/ -p wa -k scope"
    - "#确保收集了任意访问控制权限修改事件"
    - "-a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod"
    - "-a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod"
    - "-a always,exit -F arch=b64 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod"
    - "-a always,exit -F arch=b32 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod"
    - "-a always,exit -F arch=b64 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=1000 -F auid!=4294967295 -k perm_mod"
    - "-a always,exit -F arch=b32 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=1000 -F auid!=4294967295 -k perm_mod"
    - "#确保收集了修改日期和时间信息的事件"
    - "-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change"
    - "-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time- change"
    - "-a always,exit -F arch=b64 -S clock_settime -k time-change"
    - "-a always,exit -F arch=b32 -S clock_settime -k time-change"
    - "-w /etc/localtime -p wa -k time-change"
  notify: restart auditd
  tags: audit

- name: restart auditd
  #service: enabled=true name=auditd state=restarted
  command: service auditd restart
  tags: audit

复制代码

4.入侵防范

1.应遵循最小安装的原则,仅安装需要的组件和应用程序。 2.应关闭不需要的系统服务、默认共享和高危端口。 3.应通过设定终端接入方式或网络地址范围对通过网络进行管理的管理终端进行限制。 4.应提供数据有效性检验功能,保证通过人机接口输入或通过通信接口输入的内容符合系统设定要求。 5.应能通过使用漏洞扫描工具、人工漏洞排查分析等漏洞检查手段,及时发现可能存在的已知漏洞,并在经过充分测试评估后,及时修补漏洞。 6.应能够检测到对重要节点进行入侵的行为,并在发生严重入侵事件时提供报警。 7.所有安全计算环境设备应全部专用化,不得进行与业务不相关的操作。 8.应能够有效屏蔽系统技术错误信息,不得将系统产生的错误信息直接或间接反馈到前台界面。

我们针对此项标准具体限制如下:

  • 禁止终端因control-alt-delete操作导致系统重启
  • 关闭不需要的服务
# 禁止终端因control-alt-delete操作导致系统重启
- name: Centos7 ban control-alt-delete
  file:
    path: /usr/lib/systemd/system/ctrl-alt-del.target
    state: absent
  when: ansible_distribution_major_version == "7"
  tags: safe

- name: Centos6 ban control-alt-delete
  lineinfile:
    path: /etc/init/control-alt-delete.conf
    regexp: "start on control-alt-delete"
    line: "#start on control-alt-delete"
  when: ansible_distribution_major_version == "6"
  tags: safe

# 关闭不需要的服务 
- name: os close service
  service:
    name: "{{ item }}"
    state: stopped 
    enabled: no
  with_items:
    - "httpd"
    - "postfix"
    - "sendmail"
    - "autofs"
  ignore_errors: yes
  tags: safe
复制代码

5.小结

本次Ansible并没将所有的安全控制点全部实现,某些控制点需要结合安全部门及相关安全产品做进一步的管控,因此我们就不做过多的介绍了。但是在操作系统层面,我们运维还是要将控制点合理的限制在等保合规基线范围内,我认为最好的效果就是一次投入、持续受用

总结

等保的合规基线是不断调整的,因此我们也要及时关注并更新Ansible Playbook的相关task。另外,换一个角度看等保合规基线其实也是给我们指明了操作系统配置的一个方向,大家再也不用为没有统一标准发愁了,有了参照相信我们一定能够做出一套非常完美的模板来。

猜你喜欢

转载自juejin.im/post/7109260956651225119