새소식

IaC/Ansible

[A101 Study 4주차] 보안 설정 자동화

  • -

CloudNet@ 팀의 가시다님께서 Leading 하시는 A101 Study 4주차 스터디 내용 정리

 

 

해당 스터디는 '앤서블로 시작하는 인프라 자동화' 책을 기반으로 진행하였습니다.
실습 환경은 'Control Node 1 대 + Target Node 3대' 로 구성하였습니다.



1. 보안 설정 자동화

 

리눅스 운영체제에서 앤서블을 이용하여 효율적으로 시스템 보안을 적용하는 방법에 대해 알아보겠습니다.

 

 

1.1. 패스워드 변경 주기 설정

 

상황

 

리눅스 보안의 가장 기본은 패스워드 변경 주기를 설정하는 일입니다.
패스워드 변경 주기는 보통 90일입니다.

 

사전 분석

 

  1. 패스워드 변경 주기를 설정할 대상 호스트는 인벤토리를 통해 설정한다.
  2. 패스워드 변경 주기를 설정할 사용자 계정 정보와 최대 변경일은 변수를 통해 별도의 파일로 정의한다.
  3. 패스워드 변경 주기 설정은 ansible.builtin.user 모듈을 이용한다.

 

플레이북 설계

 

  • 사용자 계정과 최대 변경일을 변수로 설정하기 위해 vars_maxdays.yml 파일 생성
  • 메인 플레이북 set_chage_password.yml 파일에는 변경 주기를 설정할 태스트가 포함

 

플레이북 개발

 

- vars_maxdays.yml

---

Userinfo:
  - username: ansible
    maxdays: 90
  - username: stack
    maxdays: 90

 

 

- set_change_password.yml

---

- hosts: tnode
  vars_files: vars_maxdays.yml

  tasks:
    - name: Change Password Maxdays
      ansible.builtin.user:
        name: "{{ item.username }}"
        password_expire_max: "{{ item.maxdays }}"
      loop: "{{ Userinfo }}"

 

플레이북 실행

 

플레이북을 실행하기 전과 후의 비밀번호 변경 주기를 확인하면 변경 주기가 90일로 변경된 것을 알 수 있습니다.

 

# 플레이북 실행 전 비밀번호 변경 주기
for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i sudo chage -l ansible; echo; done

# 플레이북 실행
ansible-playbook set_change_password.yml

# 플레이북 실행 후 비밀번호 변경 주기
for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i sudo chage -l ansible; echo; done

 



 

1.2. 패스워드 생성 법칙 적용

 

상황

 

패스워드 변경 주기와 함께 반드시 설정해야 하는 보안 설정이 바로 패스워드 생성 법칙 적용입니다.

 

사전분석

 

  1. 패스워드 생성 법칙 적용을 위해서는 pwquality.conf 라는 pam 설정 파일을 이용해야 하며, 리눅스 서버에 libpam-pwquality 패키지가 있어야 함.
  2. 패스워드 변경 주기는 /etc/securiy/pwquality.conf 파일로 설정한다.
  3. /etc/securiy/pwquality.conf 파일을 설정하기 전에 원본 파일을 백업받는다.
  4. pwquality.conf 파일은 사용자가 커스텀으로 설정하는 파라미터들로 구성되어 있으며, Jinja2 템플릿 방식으로 구현한다.
  5. 파라미터들은 별도의 변수 설정 파일에서 정의한 파라미터 값으로 사용하고, 파라미터 정의 여부를 체크하여 pwquality.conf 파일의 내용을 구성한다.

 

플레이북 설계

 

  • 변수 vars_pw_rule.yml 에 정의
    • 최소 패스워드 길이 설정 minlen
    • 최소 숫자 개수 설정 dcredit
    • 최소 대문자 개수 설정 ucredit
    • 최소 소문자 개수 설정 lcredit
    • 최소 특수문자 개수 설정 ocredit
    • root 계정에서도 해당 패스워드 룰을 설정할 수 있는 enforce_for_root
  • Jinja2 템플릿 파일 pwqulity.conf.j2 아래 내용 포함
    • minlen, dcredit, ucredit, lcredit, orcedit, enforce_for_root
    • minclass : 최소 문자클래스 개수
    • maxrepeat : 최대 연속 동일 문자 수
    • maxclassrepeat : 동일 글래스의 최대 연속 문자 수

 

플레이북 개발

 

- vars_pw_rule.yml

---

minlen: 8
dcredit: -1
ucredit: -1
lcredit: -1
ocredit: -1
enforce_for_root: false

 

 

- pwquality.conf.j2

  • 암호 설정을 위한 파일은 Jinja2 템플릿을 사용하여 정의합니다.
# Created by ansible

{% if minlen is defined %}
# Minimum acceptable size for the new password
minlen = {{ minlen }}
{% endif %}

{% if dcredit is defined %}
# The maximum credit for having digits in the new password
dcredit = {{ dcredit }}
{% endif %}

{% if ucredit is defined %}
# The maximum credit for having uppercase characters in the new password
ucredit = {{ ucredit }}
{% endif %}

{% if lcredit is defined %}
# The maximum credit for having lowercase characters in the new password
lcredit = {{ lcredit }}
{% endif %}

{% if ocredit is defined %}
# The maximum credit for having other characters in the new password
ocredit = {{ ocredit }}
{% endif %}

{% if minclass is defined %}
# The minimum number of required classes of characters for the new password
minclass = {{ minclass }}
{% endif %}

{% if maxrepeat is defined %}
# The maximum number of allowed consecutive same characters in the new password
maxrepeat = {{ maxrepeat}}
{% endif %}

{% if maxclassrepeat is defined %}
# The maximum number of allowed consecutive characters of the same class in the new password
maxclassrepeat = {{ maxclassreapt }}
{% endif %}

{% if retry is defined %}
# Prompt user at most N times before returning with error
retry = {{ retry }}
{% endif %}

{% if enforce_for_root is defined %}
# Enforces pwquality checks on the root user password.
enforce_for_root
{% endif %}

 

- set_password_rule.yml

---

- hosts: tnode
  vars_files: vars_pw_rule.yml

  tasks:
    - name: Install libpam-pwquality
      ansible.builtin.apt:
        name: libpam-pwquality
        state: present
      when: ansible_facts.os_family == "Debian"

    - name: Backup pwquality.conf
      ansible.builtin.copy:
        src: /etc/security/pwquality.conf
        dest: /etc/security/pwquality.conf.bak
        remote_src: yes

    - name: Copy pwquality.conf.j2 at /etc/security
      ansible.builtin.template:
        src: pwquality.conf.j2
        dest: /etc/security/pwquality.conf
        mode: '0644'

 

플레이북 실행

 

# 플레이북 실행
ansible-playbook set_password_rule.yml

# 플레이북 실행 후 암호 설정 파일 확인
for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i sudo cat /etc/security/pwquality.conf; echo; done

 

 

실제 대상 노드에 접근하여 조건에 맞지 않는 암호 변경 시 다음과 같은 오류를 확인할 수 있습니다.

 

 

1.3. 디렉터리 및 파일 접근 권한 변경

 

상황

 

리눅스 보안 중에 꼭 확인해야 할 항목이 바로 Sticky Bit 설정 파일World Writable 설정 파일입니다.

 

  • Sticky Bit 파일
    리눅스에서 파일 소유자나 그룹 소유자만 해당 파일을 읽고 삭제할 수 있도록 권한을 부여한 것을 의미합니다.

 

  • World Writable 파일
    모든 사용자에게 파일을 읽고 쓸 수 있는 권한이 부여된 파일을 의미합니다.

 

사전 분석

 

  • Sticky bit 파일 검색 명령어: find / -xdev -perm -04000 -o -perm -02000 -o -perm -01000
  • World Writable 파일 검색 명령어: find / -xdev -type f -perm -2
  • ansible.builtin.shell 모듈을 이용하여 Sticky bit 파일과 World Writable 파일을 찾는다.
  • 찾은 파일 목록은 ansible.builtin.file 모듈을 이용하여 파일의 접속 권한을 설정한다.
  • Sticky bit 파일은 u-s, g-s, o-s 로 설정하고, World Writable 파일은 o-w 로 설정한다.

 

플레이북 설계

 

Inventory 파일 과 작업을 수행할 메인 플레이북 하나면 충분합니다.

 

- set_sticky_writable_files.yml

---

- hosts: tnode

  tasks:
  - name: Find Sticky bit files
    ansible.builtin.shell: |
      find / -xdev -perm -04000 -o -perm -02000 -o -perm 01000 \
      | grep -e 'dump$' \
             -e 'lp*-lpd$' \ 
             -e 'newgrp$' \
             -e 'restore$' \
             -e 'at$' \
             -e 'traceroute$' | xargs ls
    register: sfile_list

  - name: Find World Writable files
    ansible.builtin.shell: |
      find / -xdev -perm -2 -ls \
      | grep -v 'l..........' | awk '{print $NF}'
    register: wfile_list

  - name: Print Sticky bit files
    ansible.builtin.debug:
      msg: "{{ sfile_list.stdout_lines }}"

  - name: Print World Writable files
    ansible.builtin.debug:
      msg: "{{ wfile_list.stdout_lines }}"

  - name: Set Sticky bit files
    ansible.builtin.file:
      path: "{{ item }}"
      mode: "u-s,g-s,o-s"
    loop: "{{ sfile_list.stdout_lines }}"

  - name: Set World Writable files
    ansible.builtin.file:
      path: "{{ item }}"
      mode: "o-w"
    loop: "{{ wfile_list.stdout_lines }}"

 

 

플레이북 실행

 

각 노드에서 발견한 Sticky bit 파일 목록World Writable 파일 목록, 해당 파일 권한이 수정된 것을 확인할 수 있습니다.

# 플레이북 실행
ansible-playbook set_sticky_writable_files.yml

 

 

Contents

포스팅 주소를 복사했습니다