基於ansible的生產環境部署構建(七) 角色security_reinforce

角色功能說明:

  • 該角色實現對客戶端主機的安全加固和規避以及回滾功能

角色部署:

  • 創建目錄結構,創建軟連接,關聯默認變量文件
WorkDir=~/devops/ansible/os_init && cd ${WorkDir}
RoleName=security_reinforce
mkdir -pv roles/${RoleName}/{defaults,files,handlers,meta,tasks,templates,vars}
ln -s ${WorkDir}/defaults_var.yml roles/${RoleName}/defaults/main.yml
  • 配置系統密碼加固模版文件
cat >roles/${RoleName}/templates/login.defs_centos6.j2<<EOF
MAIL_DIR        /var/spool/mail
PASS_MAX_DAYS   90
PASS_MIN_DAYS   7
PASS_MIN_LEN    8
PASS_WARN_AGE   30
UID_MIN                   500
UID_MAX                 60000
GID_MIN                   500
GID_MAX                 60000
CREATE_HOME     yes
UMASK           077
USERGROUPS_ENAB yes
ENCRYPT_METHOD SHA512
EOF
cat >roles/${RoleName}/templates/login.defs_centos7.j2<<EOF
MAIL_DIR        /var/spool/mail
PASS_MAX_DAYS   90
PASS_MIN_DAYS   7
PASS_MIN_LEN    8
PASS_WARN_AGE   30
UID_MIN                  1000
UID_MAX                 60000
SYS_UID_MIN               201
SYS_UID_MAX               999
GID_MIN                  1000
GID_MAX                 60000
SYS_GID_MIN               201
SYS_GID_MAX               999
CREATE_HOME     yes
UMASK           077
USERGROUPS_ENAB yes
ENCRYPT_METHOD SHA512
EOF
  • 配置系統密碼pam加固模版文件
cat >roles/${RoleName}/templates/system-auth-ac_centos6.j2<<EOF
auth        required      pam_env.so
auth        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 500 quiet
auth        required      pam_deny.so
account     required      pam_unix.so
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 500 quiet
account     required      pam_permit.so
password    requisite     pam_cracklib.so minlen=8 dcredit=-1 ucredit=-1 ocredit=-1 lcredit=-1 enforce_for_root try_first_pass retry=3 type=
password    required      pam_pwhistory.so use_authtok remember=3 enforce_for_root
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password    required      pam_deny.so
session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so
EOF
cat >roles/${RoleName}/templates/system-auth-ac_centos7.j2<<EOF
auth        required      pam_env.so
auth        required      pam_faildelay.so delay=2000000
auth        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 1000 quiet_success
auth        required      pam_deny.so
account     required      pam_unix.so
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 1000 quiet
account     required      pam_permit.so
password    requisite     pam_pwquality.so minlen=8 dcredit=-1 ucredit=-1 ocredit=-1 lcredit=-1 enforce_for_root try_first_pass local_users_only retry=3 authtok_type=
password    required      pam_pwhistory.so use_authtok remember=3 enforce_for_root
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password    required      pam_deny.so
session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
-session     optional      pam_systemd.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so
EOF
  • 配置sshd pam加固模版文件
cat >roles/${RoleName}/templates/sshd_centos6.j2<<EOF
auth       required     pam_tally2.so even_deny_root deny=4 unlock_time=120 root_unlock_time=600
auth       required     pam_sepermit.so
auth       include      password-auth
account    required     pam_nologin.so
account    include      password-auth
password   include      password-auth
session    required     pam_selinux.so close
session    required     pam_loginuid.so
session    required     pam_selinux.so open env_params
session    required     pam_namespace.so
session    optional     pam_keyinit.so force revoke
session    include      password-auth
EOF
cat >roles/${RoleName}/templates/sshd_centos7.j2<<EOF
auth       required     pam_tally2.so even_deny_root deny=4 unlock_time=120 root_unlock_time=600
auth       required     pam_sepermit.so
auth       substack     password-auth
auth       include      postlogin
-auth      optional     pam_reauthorize.so prepare
account    required     pam_nologin.so
account    include      password-auth
password   include      password-auth
session    required     pam_selinux.so close
session    required     pam_loginuid.so
session    required     pam_selinux.so open env_params
session    required     pam_namespace.so
session    optional     pam_keyinit.so force revoke
session    include      password-auth
session    include      postlogin
-session   optional     pam_reauthorize.so prepare
EOF
  • 配置su pam加固模版文件
cat >roles/${RoleName}/templates/su_centos6.j2<<EOF
auth            sufficient      pam_rootok.so
auth            required        pam_wheel.so use_uid
auth            include         system-auth
account         sufficient      pam_succeed_if.so uid = 0 use_uid quiet
account         include         system-auth
password        include         system-auth
session         include         system-auth
session         optional        pam_xauth.so
EOF
cat >roles/${RoleName}/templates/su_centos7.j2<<EOF
auth            sufficient      pam_rootok.so
auth            required        pam_wheel.so use_uid
auth            substack        system-auth
auth            include         postlogin
account         sufficient      pam_succeed_if.so uid = 0 use_uid quiet
account         include         system-auth
password        include         system-auth
session         include         system-auth
session         include         postlogin
session         optional        pam_xauth.so
EOF
  • 創建系統密碼規避策略腳本
cat >roles/${RoleName}/files/userPass.sh<<EOF
#!/bin/bash
source ~/.bash_profile
ChangeDateStr=\$(date +%F)
ExpireDateStr=\$(date -d'90 days' +%F)
for user in \$(grep bash /etc/passwd|awk -F':' '{print \$1}')
do chage -d \${ChangeDateStr} -E \${ExpireDateStr} \${user};done
EOF
  • 創建角色任務
cat >roles/${RoleName}/tasks/main.yml<<\EOF
---
- name: "系統用戶密碼加固"
  template:
    src: login.defs_centos{{ ansible_distribution_major_version }}.j2
    dest: /etc/login.defs
    backup: yes
    force: yes
    owner: root
    group: root
    mode: 0644
- name: "已存在系統用戶密碼加固"
  shell:
    "for user in $(grep bash /etc/passwd|awk -F':' '{print $1}'); \
    do chage -m 7 -M 90 -W 30 -d $(date +%F) -E $(date -d'90 days' +%F) ${user};done"
- name: "分發系統用戶密碼加固腳本"
  copy:
    src: userPass.sh
    dest: /root/checkOS
    owner: root
    group: root
    mode: 0644
- name: "部署系統用戶密碼加固規避任務"
  cron:
    name: "userPass"
    job: "/bin/bash /root/checkOS/userPass.sh"
    minute: "0"
- name: "系統用戶密碼pam加固"
  template:
    src: system-auth-ac_centos{{ ansible_distribution_major_version }}.j2
    dest: /etc/pam.d/system-auth-ac
    backup: yes
    force: yes
    owner: root
    group: root
    mode: 0644
- name: "sshd 防暴力破解pam加固"
  template:
    src: sshd_centos{{ ansible_distribution_major_version }}.j2
    dest: /etc/pam.d/sshd
    backup: yes
    force: yes
    owner: root
    group: root
    mode: 0644
- name: "創建sudoler用戶"
  user:
    name: sudoler
    createhome: yes
    groups: wheel
- name: "分發ssh公鑰到sudoler用戶"
  authorized_key:
      user: sudoler
      key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
      state: present
- name: "限制su pam加固"
  template:
    src: su_centos{{ ansible_distribution_major_version }}.j2
    dest: /etc/pam.d/su
    backup: yes
    force: yes
    owner: root
    group: root
    mode: 0644
- name: "限制root ssh登陸"
  lineinfile:
    path: /etc/ssh/sshd_config
    regexp: "^PermitRootLogin"
    line: "PermitRootLogin no"
- name: "關閉最後一次ssh登陸信息打印"
  lineinfile:
    path: /etc/ssh/sshd_config
    regexp: "^PrintLastLog"
    line: "PrintLastLog no"
- name: "打開ssh登陸後的公告信息"
  lineinfile:
    path: /etc/ssh/sshd_config
    regexp: "^PrintMotd"
    line: "PrintMotd yes"
- name: "配置公告信息內容"
  copy:
    dest: /etc/motd
    content: "##################################################\n\
#\t{{ target_hostname_prefix }}-{{ ansible_ssh_host }} 登陸成功\n\
##################################################\n"
- name: "重啓sshd服務生效加固項"
  service:
    name: sshd
    state: restarted
- name: "會話超時自動退出"
  lineinfile:
    path: /etc/profile
    line: "export TMOUT=180"
- name: "關閉命令歷史記錄"
  lineinfile:
    path: /etc/profile
    regexp: "^HISTSIZE"
    line: "HISTSIZE=0"
- name: "不迴應ping命令"
  lineinfile:
    path: /etc/sysctl.conf
    regexp: "^net.ipv4.icmp_echo_ignore_all"
    line: "net.ipv4.icmp_echo_ignore_all = 1"
- name: "執行命令使配置生效"
  shell:
    "source /etc/profile && sysctl -p"
EOF
  • 創建任務playbook並執行
cat >os-init-6.1-${RoleName}-root-setupAll.yml<<EOF
---
- hosts: all
  remote_user: root
  gather_facts: true
  become: no
  roles:
    - ${RoleName}
EOF
ansible-playbook -i inventory/hosts os-init-6.1-${RoleName}-root-setupAll.yml

重要功能補充:

  • 加固項中最爲關鍵的是root ssh遠程登陸限制,該項加固回滾策略爲:
ansible all -i inventory/hosts -u sudoler -b --become-method=su --become-user=root \
  -m lineinfile -a "path=/etc/ssh/sshd_config regexp='^PermitRootLogin' line='PermitRootLogin yes'" -K
ansible all -i inventory/hosts -u sudoler -b --become-method=su --become-user=root \
  -m service -a "name=sshd state=restarted" -K
  • 注意:安全加固後,sudoler用戶只能通過ssh免密登陸,無法通過密碼登陸

  • 技巧:可以使用-e傳入密碼來代替-K操作實現非交互

ansible all -i inventory/hosts -u sudoler -b --become-method=su --become-user=root -e 'ansible_become_pass'="vincent" \
  -m lineinfile -a "path=/etc/ssh/sshd_config regexp='^PermitRootLogin' line='PermitRootLogin yes'"
ansible all -i inventory/hosts -u sudoler -b --become-method=su --become-user=root -e 'ansible_become_pass'="vincent" \
  -m service -a "name=sshd state=restarted"
  • 執行過安全加固後,root用戶ssh登陸被限制,需要修改os-init.yml後才能再次執行
  • 如果是第一次執行,則不能使用sudoler作爲執行用戶,因爲安全加固之前沒有該用戶
cat >os-init-6.2-${RoleName}-sudoler-resetupAll.yml<<EOF
---
- hosts: all
  remote_user: sudoler
  gather_facts: true
  become: yes
  become_user: root
  become_method: su
  roles:
    - ${RoleName}
EOF
ansible-playbook -i inventory/hosts os-init-6.2-${RoleName}-sudoler-resetupAll.yml
  • 以playbook的方式回滾掉root遠程登陸限制:
cat >os-init-6.3-${RoleName}-sudoler-rollbackRootssh.yml<<EOF
---
- hosts: all
  remote_user: sudoler
  gather_facts: false
  become: yes
  become_user: root
  become_method: su
  tasks:
  - name: "剔除sshd配置"
    lineinfile:
      path: /etc/ssh/sshd_config
      regexp: '^PermitRootLogin'
      line: 'PermitRootLogin yes'
  - name: "重啓sshd服務"
    service:
      name: sshd
      state: restarted
EOF
ansible-playbook -i inventory/hosts -e 'ansible_become_pass'="vincent" os-init-6.3-${RoleName}-sudoler-rollbackRootssh.yml
  • 重新設置root遠程登陸限制:
cat >os-init-6.4-${RoleName}-sudoler-resetupRootssh.yml<<EOF
---
- hosts: all
  remote_user: sudoler
  gather_facts: false
  become: yes
  become_user: root
  become_method: su
  tasks:
  - name: "添加sshd配置"
    lineinfile:
      path: /etc/ssh/sshd_config
      regexp: '^PermitRootLogin'
      line: 'PermitRootLogin no'
  - name: "重啓sshd服務"
    service:
      name: sshd
      state: restarted
EOF
ansible-playbook -i inventory/hosts -e 'ansible_become_pass'="vincent" os-init-6.4-${RoleName}-sudoler-resetupRootssh.yml

TOC

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章