보안설정/모니터링 자동화
1. 보안설정 자동화
패스워드 변경 주기 설정하기
사전 분석
- 패스워드 변경 주기를 설정할 대상 호스트는 인벤토리를 통해 설정한다.
- 패스워드 변경 주기를 설정할 사용자 계정 정보와 최대 변경일은 변수를 통해 별도의 파일로 정의한다.
- 패스워드 변경 주기 설정은
ansible.builtin.user
모듈을 이용한다.
플레이북 설계
- 사용자 계정과 최대 변경일을 변수로 설정하기 위해 vars_maxdays.yml 파일 생성
- 메인 플레이북 set_chage_password.yml 파일에는 변경 주기를 설정할 태스트가 포함
- ansilble.cfg / inventory/ 변수 / 플레이북 작성
- ansible.cfg
cat ansible.cfg
[defaults]
inventory = ./inventory
remote_user = ubuntu
ask_pass = false
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
- inventory
cat inventory
[tnode]
tnode1
tnode2
tnode3
- 변수 작성
# ansible, stack의 최대 비밀번호 사용 기간은 90일
cat vars_maxdays.yml
Userinfo:
- username: ansible
maxdays: 90
- username: stack
maxdays: 90
- 플레이북 작성
# tnode 그룹에서 실행됨
# 변수 정보는 vars_maxdays.yml 참조
# ansible.builtin 모듈을 사용하여 name, password_expire_max의 값을
# 변수를 참조하여 설정
cat set_chage_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 }}"
- 실행 화면 및 확인
- 실행
- 확인
패스워드 생성 법칙 적용하기
사전분석
- 패스워드 생성 법칙 적용을 위해서는 pwquality.conf 라는 pam 설정 파일을 이용해야 하며, 리눅스 서버에 libpam-pwquality 패키지가 있어야 함.
- 패스워드 변경 주기는 /etc/securiy/pwquality.conf 파일로 설정한다.
- /etc/securiy/pwquality.conf 파일을 설정하기 전에 원본 파일을 백업받는다.
- pwquality.conf 파일은 사용자가 커스텀으로 설정하는 파라미터들로 구성되어 있으며, Jinja2 템플릿 방식으로 구현한다.
- 파라미터들은 별도의 변수 설정 파일에서 정의한 파라미터 값으로 사용하고, 파라미터 정의 여부를 체크하여 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 : 동일 글래스의 최대 연속 문자 수
- ansilble.cfg / inventory/ 변수 / 플레이북 작성
- ansible.cfg
cat ansible.cfg
[defaults]
inventory = ./inventory
remote_user = ubuntu
ask_pass = false
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
- inventory
cat inventory
[tnode]
tnode1
tnode2
tnode3
- 변수 작성
cat vars_pw_rule.yml
---
minlen: 8
dcredit: -1
ucredit: -1
lcredit: -1
ocredit: -1
enforce_for_root: true
- Jinja2 템플릿 파일 pwquality.conf.j2 작성
{% ~ %}
사이에 제어문 구문 위치{% if minlen is defined %}
구문 : minlen 이라는 변수가 정의되면 아래 문장을 삽입하라’ 는 의미- 아래 템플릿에는
{% if 변수 is defined %}
~{% endif %}
구문을 사용하여 파라미터와 관련된 변수가 선언되면 해당 파라미터를 삽입 # 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 %}
- 플레이북 작성
# tnode 그룹에서 실행됨
# 변수 정보는 vars_pw_rule.yml 참조
# ansible.builtin 모듈을 사용하여 libpam-pwqualit 패키지 설치
# 기존에 있던 pwquality.conf 파일을 백업
# ansible을 실행하는 곳의 pwquality.conf.j2 파일을 node로 이동
cat 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 == "Ubuntu"
- 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'
- remote_src : yes를 해주지 않는다면 로컬에서 node로 파일을 복사하려하기 때문에 꼭 기입해줘야 한다
- 실행 및 확인
- 플레이북 실행
- 테스크 실행 확인
- 패스워드 변경 실행 ( qwer123, qwer1234 입력시 경고 메세지 출력 확인)
디렉토리 및 파일 접근 권한 변경
상황
- 리눅스 보안 중에 꼭 확인해야 하는 항목이 바로 Sticky bit 설정 파일과 World Writable 설정 파일입니다.
- Sticky bit 설정 파일은 리눅스에서 파일 소유자나 그룹 소유자만 해당 파일을 읽고 쓰고 삭제할 수 있도록 권한을 부여한 것을 의미합니다.
- 파일 소유자에게 권한을 부여하면 SUID, 파일 그룹에게 권한을 부여하면 SGID, 다른 사람에게 권한을 부여하면 Sticky bit 라고 합니다.
- Sticky bit가 적용된 파일 목록 중 보안을 위해 이를 적용하면 안 되는 파일 목록들이 있습니다.
- 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 로 설정한다.
플레이북 설계
- ansilble.cfg / inventory/ 변수 / 플레이북 작성
- ansible.cfg
cat ansible.cfg
[defaults]
inventory = ./inventory
remote_user = ubuntu
ask_pass = false
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
- inventory
cat inventory
[tnode]
tnode1
tnode2
tnode3
- 플레이북 작성
cat 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 }}"
- 실행 및 확인
- 실행
- 확인
2. 모니터링 자동화
팩트를 이용한 시스템 모니터링
사전분석
- 팩트는 관리 노드에서 시스템과 관련된 정보(아래 예시)들을 찾아 변수로 제공 → 인프라 정보 파악 및 로그로 저장
- 호스트 이름
- 커널 버전
- 네트워크 인터페이스 이름
- 네트워크 인터페이스 IP 주소
- 운영체제 버전
- CPU 개수
- 사용 가능한 메모리
- 스토리지 장치의 크기 및 여유 공간
- 추출한 내용은
ansible.builtin.shell
모듈을 이용하여 /var/log/daily_check 디렉터리에 저장
플레이북 설계
- ansible.cfg / inventory / 변수 / 플레이북 작성
- ansible.cfg
cat ansible.cfg
[defaults]
inventory = ./inventory
remote_user = ubuntu
ask_pass = false
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
- inventory
cat inventory
[tnode]
tnode1
tnode2
tnode3
- 플레이북 작성 : debug과 facts 수집 후 file 에 저장
---
- hosts: tnode
vars:
log_directory: /var/log/daily_check
tasks:
- name: Print system info
ansible.builtin.debug:
msg:
- "################ Start #####################"
- "Date: {{ ansible_facts.date_time.date }} {{ ansible_facts.date_time.time }}"
- "HostName: {{ ansible_facts.hostname }}"
- "OS: {{ ansible_facts.distribution }}"
- "OS Version: {{ ansible_facts.distribution_version }}"
- "OS Kernel: {{ ansible_facts.kernel }}"
- "CPU Cores: {{ ansible_facts.processor_vcpus }}"
- "Memory: {{ ansible_facts.memory_mb.real }}"
- "Interfaces: {{ ansible_facts.interfaces }}"
- "IPv4: {{ ansible_facts.all_ipv4_addresses }}"
- "Devices: {{ ansible_facts.mounts }}"
- "################# End #######################"
register: result
- name: Create log directory
ansible.builtin.file:
path: "{{ log_directory }}"
state: directory
- name: Print logs to log file
ansible.builtin.shell: |
echo "{{ item }}" >> "{{ log_directory }}"/system_info.logs
loop: "{{ result.msg }}"
- 실행 및 확인
- 실행
- 확인
CPU, 메모리, 디스크 사용률 모니터링
사전분석
- 팩트에서 제공되지 않은 정보를 모니터링해야되는 상황
- 자세한 CPU, 메모리, 디스크 사용률 모니터링을 위해 dstat, iostat, vmstat 명령어 사용 → 툴 설치 필요
- 각각의 명령어 실행은
ansible.builtin.shell
이용하여 실행하고, loop 키워드를 이용하여 모니터링 명령어별로 여러 옵션을 추가하여 명령 실행 - 실행된 명령어 결과는 로그 디렉터리에 저장
플레이북 설계
- ansible.cfg / inventory / 변수 / 플레이북 작성
- ansible.cfg
cat ansible.cfg
[defaults]
inventory = ./inventory
remote_user = ubuntu
ask_pass = false
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
- inventory
cat inventory
[tnode]
tnode1
tnode2
tnode3
- 변수 작성
cat vars_packages.yml
---
log_directory: /home/ansible/logs
packages:
- dstat
- sysstat
- 플레이북 작성 : debug와 facts 수집 후 file 에 저장
# node의 os는 ubuntu 이므로 apt를 활용하여 dstat, sysstat 설치
# log저장을 위한 디렉토리 생성
# dstat 2 10 , dstat -cmdlt -D vda 2 10 명령어를 각각 실행하여 dstat.log에 저장
# iostat 등의 명령어를 각각 실행하여 iostat.log에 저장
# vmstat 등의 명령어를 각각 실행하여 vmstat.log에 저장
cat monitoring_system.yml
---
- hosts: tnode
vars_files: vars_packages.yml
tasks:
- name: Install packages on RedHat
ansible.builtin.dnf:
name: "{{ item }}"
state: present
loop: "{{ packages }}"
when: ansible_facts.os_family == "RedHat"
- name: Install packages on Ubuntu
ansible.builtin.apt:
name: "{{ item }}"
state: present
loop: "{{ packages }}"
when: ansible_facts.os_family == "Debian"
- name : creat directory
ansible.builtin.file:
path: "{{ log_directory }}"
state: directory
- name: Monitoring dstat
ansible.builtin.shell: |
{{ item }} >> {{ log_directory }}/dstat.log
loop:
- dstat 2 10
- dstat -cmdlt -D vda 2 10
- name: Monitoring iostat
ansible.builtin.shell: |
{{ item }} >> {{ log_directory }}/iostat.log
loop:
- iostat
- echo "==============="
- iostat -t -c -dp vda
- echo "==============="
- name: Monitoring vmstat
ansible.builtin.shell: |
{{ item }} >> {{ log_directory }}/vmstat.log
loop:
- vmstat
- echo "==============="
- vmstat -dt
- echo "==============="
- vmstat -D
- echo "==============="
- name: Monitoring df
ansible.builtin.shell: |
df -h >> {{ log_directory }}/df.log
- 실행 및 확인
- 실행
- 확인 - 각로그 존재 확인
'Ansible > Study' 카테고리의 다른 글
시스템 구축 및 환경 설정 자동화 (0) | 2024.02.04 |
---|---|
Ansible - 반복문, 조건문, 핸들러 ,롤 구조 (0) | 2024.01.20 |
Ansible 기초 정리 (0) | 2024.01.09 |