티스토리 뷰

반응형

배경

GCP에 대형(?) Wazuh를 구축 및 기존에 사용하던 구 Wazuh 클러스터에서 이전해야 함에 따라서,

모든 사내 인스턴스들에 새로이 Wazuh agent가 설치되어야 했다.

그러려면 일일이 몇 천대의 서버에 접속해서 에이전트를 설치할 수도 없는 노릇이었고,

하나의 배포 파일에서 OS와 기존 설치여부에 따른 경우의 수를 조건문에서 분기하여 설치가 가능해야 했다.

 

다시! 여기서는 단순히 지원하는 에이전트 설치 파일을 배포하는 것이 아닌,

전 사의 서버 환경에 맞게 하나의 파일로 에이전트를 설치할 수 있는 스크립트를 제작하는 것이 주제이며,

📛 이 글에는 CentOS, Ubuntu 에이전트만 대상으로 고려되어 있다.

 

 

 

사전 조사

설치 지원 OS

사내 서버들이 Wazuh 에이전트 설치를 지원하는 OS에 속하는지 사전 조사가 필요하다.

Wazuh는 오픈소스 플랫폼으로 에이전트 설치 파일을 기본적으로 제공하고 있지만,

지원 가능한 OS 및 아키텍처여야만 설치가 가능하기 때문이다.

웬만한 Unix 계열을 비롯해 Windows, Mac, Solaris, HP-UX, AIX도 제공한다.

https://documentation.wazuh.com/current/installation-guide/packages-list.html#wazuh-agent

 

Packages list - Installation guide · Wazuh documentation

User manual, installation and configuration guides. Learn how to get the most out of the Wazuh platform.

documentation.wazuh.com

 

방화벽 오픈 여부

에이전트가 설치될 사내 자산들과, 구축한 Wazuh 클러스터(특히 worker) 간 통신이 가능해야 한다.

필요한 통신 오픈 포트는 다음과 같다.

TCP 1515 : 에이전트의 정보를 Wazuh 클러스터에 등록하고 대시보드에서 확인하기 위함

TCP 1514 : 에이전트 등록 외 모든 통신. rule 파일을 내려주고, SCA를 동작시키고, 원격 명령을 내리는 등의 동작.

참고로 에이전트와의 통신은 TCP 55000 포트 오픈은 불필요하다.

55000은 Wazuh API로써 Wazuh 클러스터와 dashboard(kibana) 간에 오픈되면 된다.

 

폐쇄망 여부

에이전트를 설치할 서버들에 외부로 yum이나 curl 명령어가 가능한지 확인해야 한다.

만약 불가한 환경이라면, 망분리솔루션(파일전송) 등에 업로드해서 내부<->내부로 받아올 수 있다.

 

 

 

스크립트 flow 요약

1. root 권한 실행 여부

파일 배포 후 root로 해당 스크립트를 실행하는지 $EUID를 통해 확인한다.

check_root() {
    if [[ $EUID -ne 0 ]]; then
        echo "[WARN] 루트로 실행되어야 합니다."
        exit -1
    fi
}

 

2. Wazuh 서버와 그룹 지정

에이전트와 통신할 Worker(매니저 서버)의 IP와 + 에이전트의 그룹을 미리 지정해준다.

SIEM_GROUP 변수의 경우 콤마(,)를 통해 다중 그룹 지정도 한꺼번에 가능하다.

추가로 에이전트의 그룹을 아래처럼 하드코딩하지 않고,

IP 대역에 따라 할당을 자동화할 수 있는 방안이 있어 다음에 작성하려 한다.

SIEM_SERVER="aaa.bbb.ccc.ddd"
SIEM_GROUP="default,PROD"

 

3. OS 체크

get_os_version 함수로 OS Distribution을 체크한다.

get_os_version() {
    # 가장 최상위 시행 조건으로 대부분의 OS가 이 조건을 충족함 
    if [ -f /etc/os-release ]; then
        # /etc/os-release 파일의 변수를 쉘에서 사용할 수 있도록 함
        source /etc/os-release
        OS=$ID
        VER=$VERSION_ID
    # lsb_release 명령어가 있는지 확인    
    elif type lsb_release >/dev/null 2>&1; then
        OS=$(lsb_release -si)
        VER=$(lsb_release -sr)
    # /etc/lsb_release 파일이 있는지 확인 
    elif [ -f /etc/lsb-release ]; then
        source /etc/lsb-release
        OS=$DISTRIB_ID
        VER=$DISTRIB_RELEASE
    # /etc/debian_version 파일이 있는지 확인 
    elif [ -f /etc/debian_version ]; then
        # Older Debian/Ubuntu/etc.
        OS=Debian
        VER=$(cat /etc/debian_version)
    # /etc/redhat-release 파일이 있는지 확인 
    elif [ -f /etc/redhat-release ]; then
        OS=$(cat /etc/redhat-release | cut -d " " -f 1) 
        VER=$(cat /etc/redhat-release | cut -d " " -f 3)
    # 그 외는 지원하지 않음 
    else
        OS=$(uname -s)
        VER=$(uname -r)
    fi
 
    echo $OS | tr [:upper:] [:lower:]
}

 

4. 에이전트 설치

외부 인터넷망을 통해 Wazuh 패키지를 받아오는 방법이다.

위에서 서술했듯 폐쇄망이라면 해당 파일을 내부 서버에 업로드해서 받아올 수 있다.

# Ubuntu
curl -so wazuh-agent.deb https://packages.wazuh.com/4.x/apt/pool/main/w/wazuh-agent/wazuh-agent_4.6.0-1_amd64.deb

# CentOS
yum install -y https://packages.wazuh.com/4.x/yum/wazuh-agent-4.6.0-1.x86_64.rpm

 

5. remote_option 존재 체크

Wazuh에 에이전트를 설치하여 클러스터와 통신하기 위해서는

/var/ossec/etc/local_internal_options.conf에 다음 내용이 있어야 한다.

- wazuh_command.remote_commands=1

- sca.remote_commands=1

- logcollector.remote_commands=1

check_remote_option_existed() {
    OPTION_1=$(cat /var/ossec/etc/local_internal_options.conf 2>/dev/null | grep "wazuh_command.remote_commands=1" | wc -l)
    OPTION_2=$(cat /var/ossec/etc/local_internal_options.conf 2>/dev/null | grep "sca.remote_commands=1" | wc -l)
    OPTION_3=$(cat /var/ossec/etc/local_internal_options.conf 2>/dev/null | grep "logcollector.remote_commands=1" | wc -l)
    # 해당 옵션이 설정되지 않은 경우만 추가한다.
    if [ $OPTION_1 -eq 0 ]; then
        echo "wazuh_command.remote_commands=1" >> /var/ossec/etc/local_internal_options.conf
    fi
    if [ $OPTION_2 -eq 0 ]; then
        echo "sca.remote_commands=1" >> /var/ossec/etc/local_internal_options.conf
    fi
    if [ $OPTION_3 -eq 0 ]; then
        echo "logcollector.remote_commands=1" >> /var/ossec/etc/local_internal_options.conf
    fi
}

하지만 이미 에이전트를 설치한 이력이 있다면 계속해서 내용이 추가되는 것을 방지하기 위해,

해당 옵션이 작성되어 있지 않을 경우에만(최초 설치 시에만) 추가하도록 한다.

 

6. 에이전트 등록

regist_agent() {
    # Regist agent
    REGIST_CMD="/var/ossec/bin/agent-auth -m $SIEM_SERVER -G \"$SIEM_GROUPS\""
    # Set server IP
    sed -i "s/MANAGER_IP/$SIEM_SERVER/" /var/ossec/etc/ossec.conf
}

/var/ossec/bin/agent-auth -m $[Wazuh 매니저 IP] -G \"$[그룹]" 명령어를 통해,

Wazuh 서버와 에이전트가 통신 가능한지 확인 후 등록을 시도한다.

이후 /var/ossec/etc/ossec.conf의 MANAGER_IP 부분을 Wazuh 서버 IP로 지정하도록 한다.

-> 초기 ossec.conf는 <address>MANAGER_IP</address> 처럼 서버 IP가 지정되지 않은 상태라 대체하는 것이다.

 

7. 에이전트 서비스 시작

에이전트 등록을 마쳤다면 서비스를 시작해주어야 한다.

CentOS6의 경우는 service 명령어를 쓰고,

나머지 보통 OS는 systemctl 명령어를 사용하므로 아래와 같이 분리했다.

# wazuh-agent start on using "service" command env
start_agentd_centos6() {
    service wazuh-agent start
}

# wazuh-agent start on using "systemctl" command env
start_agentd_common() {
    systemctl enable wazuh-agent
    systemctl start wazuh-agent
}

 

 

✅ 완성 스크립트 (일부)

아래 스크립트를 통해 이제 리눅스 Wazuh 에이전트 설치 스크립트를 배포할 수 있다.

Wazuh agent 4.6 버전 기준이므로, 그 이상이나 이하 버전 사용을 원하면 조정해야 한다.

단, Wazuh manager가 agent보다 버전이 높아야 한다는 점을 유의해야 한다.

또한 🟥 --- 4. 에이전트 설치 --- 부분은, 설치 및 서비스 시작 명령어가 OS 버전별로 달라 분리하였다.

#!/bin/bash

# 🟥 ------------------------ 1. root 권한 실행 여부 ------------------------ #
check_root() {
    if [[ $EUID -ne 0 ]]; then
        echo "[WARN] root 권한으로 실행되어야 합니다."
        exit -1
    fi
}

# 🟥 ------------------------ 3. OS 체크 ------------------------ #
get_os_version() {
    if [ -f /etc/os-release ]; then
        source /etc/os-release
        OS=$ID
        VER=$VERSION_ID
    elif type lsb_release >/dev/null 2>&1; then
        OS=$(lsb_release -si)
        VER=$(lsb_release -sr)
    elif [ -f /etc/lsb-release ]; then
        source /etc/lsb-release
        OS=$DISTRIB_ID
        VER=$DISTRIB_RELEASE
    elif [ -f /etc/debian_version ]; then
        OS=Debian
        VER=$(cat /etc/debian_version)
    elif [ -f /etc/redhat-release ]; then
        OS=$(cat /etc/redhat-release | cut -d " " -f 1) 
        VER=$(cat /etc/redhat-release | cut -d " " -f 3)
    else
        OS=$(uname -s)
        VER=$(uname -r)
    fi
 
    echo $OS | tr [:upper:] [:lower:]
}

# 🟥 ------------------------ 4. 에이전트 설치 ------------------------ #
install_agent_centos() {
    # Check OS - Centos6
    CENTOS_INFO_ALL=$(cat /etc/redhat-release)
    CENTEOL=$(echo $CENTOS_INFO_ALL | grep -i "release" | cut -d "." -f1)
    CENTEOL=$(echo $CENTEOL | cut -d " " -f3)
    echo $CENTEOL

    yum install -y https://packages.wazuh.com/4.x/yum/wazuh-agent-4.6.0-1.x86_64.rpm
    echo "[INFO] Wazuh 에이전트를 설치했습니다."
 
    sleep 2
    check_remote_option_existed
    regist_agent
    
    if [[ $CENTEOL -eq 6 ]]; then
        start_agentd_centos6
    else
        start_agentd_common
    fi
 
    echo "[INFO] Wazuh 에이전트 서비스를 시작했습니다."
}

install_agent_ubuntu() {
    curl -so wazuh-agent.deb https://packages.wazuh.com/4.x/apt/pool/main/w/wazuh-agent/wazuh-agent_4.6.0-1_amd64.deb
 
    INSTALL_CMD="dpkg -i wazuh-agent.deb"
    eval $INSTALL_CMD
    echo "[INFO] Wazuh 에이전트를 설치했습니다."
 
    sleep 2
    check_remote_option_existed
    regist_agent
    start_agentd_common
 
    echo "[INFO] Wazuh 에이전트 서비스를 시작했습니다."
    rm -f wazuh-agent.deb
}

# 🟥 ------------------------ 5. remote_option 존재 체크 ------------------------ #
check_remote_option_existed() {
    OPTION_1=$(cat /var/ossec/etc/local_internal_options.conf 2>/dev/null | grep "wazuh_command.remote_commands=1" | wc -l)
    OPTION_2=$(cat /var/ossec/etc/local_internal_options.conf 2>/dev/null | grep "sca.remote_commands=1" | wc -l)
    OPTION_3=$(cat /var/ossec/etc/local_internal_options.conf 2>/dev/null | grep "logcollector.remote_commands=1" | wc -l)
    if [ $OPTION_1 -eq 0 ]; then
        echo "wazuh_command.remote_commands=1" >> /var/ossec/etc/local_internal_options.conf
    fi
    if [ $OPTION_2 -eq 0 ]; then
        echo "sca.remote_commands=1" >> /var/ossec/etc/local_internal_options.conf
    fi
    if [ $OPTION_3 -eq 0 ]; then
        echo "logcollector.remote_commands=1" >> /var/ossec/etc/local_internal_options.conf
    fi
}

# 🟥 ------------------------ 6. 에이전트 등록 ------------------------ #
regist_agent() {
    REGIST_CMD="/var/ossec/bin/agent-auth -m $SIEM_SERVER -G \"$SIEM_GROUPS\""
    eval $REGIST_CMD
    sed -i "s/MANAGER_IP/$SIEM_SERVER/" /var/ossec/etc/ossec.conf
}

# 🟥 ------------------------ 7. 에이전트 서비스 시작 ------------------------ #
start_agentd_centos6() {
    service wazuh-agent start
}
start_agentd_common() {
    systemctl enable wazuh-agent
    systemctl start wazuh-agent
}

main() {
    OSDISTRO=$(get_os_version)
    if [ "$OSDISTRO" == "ubuntu" ] || [ "$OSDISTRO" == "debian" ]; then
        install_agent_ubuntu $SIEM_SERVER $SIEM_GROUPS
    elif [ "$OSDISTRO" == "centos" ] || [ "$OSDISTRO" == "rocky" ] || [ "$OSDISTRO" == "amzn" ]; then
        install_agent_centos $SIEM_SERVER $SIEM_GROUPS
    else
        echo "ERROR: $OSDISTRO는 지원되지 않는 OS입니다."
    fi
}
 
# 🟨 여기서 스크립트를 시작합니다.
# 🟥 ------------------------ 1. root 권한 실행 여부 ------------------------ #
check_root
# 🟥 ------------------------ 2. Wazuh 서버와 그룹 지정 ------------------------ #
SIEM_SERVER="10.10.10.10"
SIEM_GROUPS="default"

main

 

 

완료 후기

해당 파일을 배포하기 위해서 망분리솔루션의 파일 서버에 해당 파일을 업로드한 뒤,

인프라담당자가 curl로 받아와서 권한을 주고 실행하거나 각자의 방법으로 배포하도록 하였다.

파일을 배포하기 위해 ansible을 활용하는 방법도 있어보였지만 협업할 시간이 부족해 그렇게 하진 못했다.

사정 상 가장 보편적인 OS만을 고려해 스크립트를 배포하였는데

아마존 리눅스라던지, 요즘 CentOS EOL로 인해 마이그레이션 진행 중인 Rocky Linux라던지 등의 요청이 있어서

기존 CentOS와 Debian 류와 호환성을 확인하고 중간중간 $OSDISTRO 변수를 통해 추가해서 해결했다.

해당 스크립트로 지금까진 사내 에이전트 1천대 정도가 설치 완료되었고 큰 이슈는 없어 다행이고

아직 부족한 실력에 스크립트 커스터마이징하며 실제로 잘 설치됨을 확인해서 뿌듯하다.  

반응형
댓글
반응형
Recent Post.
Recent Reply.
Thanks for comming.
오늘은
명이 방문했어요
어제는
명이 방문했어요