본문 바로가기
프로그램 (PHP,Python)

Python 설치된 모듈 정보를 수집하여 보안검사 및 모니터링

by 날으는물고기 2024. 2. 14.

Python 설치된 모듈 정보를 수집하여 보안검사 및 모니터링

The General Architecture of Python

Python 모듈이 설치되는 이벤트를 수집하는 것은 여러 목적으로 유용할 수 있습니다. 예를 들어, 특정 환경에서 어떤 패키지가 설치되는지 모니터링하거나, 설치된 패키지에 대한 로그를 기록하기 위해 이를 수행할 수 있습니다. 이를 위한 주요 방법은 다음과 같습니다.

1. pip 이벤트 로깅 활성화

pip 자체에는 설치 이벤트를 로깅하는 기능이 내장되어 있습니다. pip 로그를 활성화하려면 다음과 같이 환경 변수를 설정하거나 pip 명령에 직접 로깅 옵션을 추가할 수 있습니다.

  • 환경 변수 설정:이렇게 설정하면 모든 pip 작업이 지정된 파일에 로그됩니다.
    • export PIP_LOG=/path/to/pip.log
  • pip 명령에 로깅 옵션 추가:이 방법을 사용하면 특정 pip 명령에 대한 로그만 기록할 수 있습니다.
    • pip install some-package -v --log /path/to/pip.log

2. Python 스크립트를 사용한 모니터링

Python 스크립트를 사용하여 패키지 설치 이벤트를 모니터링할 수 있습니다. 이를 위해 subprocess 모듈을 사용하여 pip 명령을 감시하고, 출력을 분석할 수 있습니다.

import subprocess

def install_and_log(package):
    result = subprocess.run(
        ["pip", "install", package],
        capture_output=True, text=True
    )
    with open("/path/to/pip.log", "a") as log_file:
        log_file.write(result.stdout)
        log_file.write(result.stderr)

install_and_log("some-package")

이 스크립트는 지정된 패키지를 설치하고, 설치 과정의 표준 출력과 오류 출력을 로그 파일에 기록합니다.

3. pip의 post-installation 스크립트 활용

일부 고급 사용자들은 pip의 post-installation 스크립트 기능을 사용하여 패키지 설치 후 추가 작업을 수행합니다. 이 방법은 커스텀 Python 패키지를 만들거나 수정할 때 유용할 수 있습니다.

4. 시스템 레벨에서의 모니터링

운영 체제 수준에서 프로세스를 모니터링하는 도구(예: Process Monitor on Windows, dtrace 또는 strace on Unix-like systems)를 사용하여 pip 프로세스를 감시하고 해당 로그를 수집할 수 있습니다. 이 방법은 시스템 관리자 레벨의 권한과 전문 지식을 요구합니다.

주의사항

  • 모든 방법에는 특정 시스템에 맞게 적절한 권한 설정과 구성이 필요합니다.
  • 로깅과 모니터링은 시스템의 성능에 영향을 줄 수 있으므로, 신중하게 설정하고 필요한 경우에만 활성화하는 것이 좋습니다.
  • 민감한 정보가 로그에 포함될 수 있으므로, 로그 파일의 보안과 관리에 주의해야 합니다.

 

Python 모듈의 악성 여부를 체크하고, 필요한 경우 알람을 보내거나 모듈을 격리하거나 삭제하는 것은 보안에 매우 중요한 일입니다. 이를 위한 접근 방법은 다음과 같습니다.

1. 설치된 모듈 목록 가져오기

먼저, 설치된 모든 Python 모듈의 목록을 가져옵니다. 이는 pip list 명령 또는 Python의 pkg_resources 라이브러리를 사용하여 수행할 수 있습니다.

 

예를 들어, pip list 명령을 사용하는 방법은 다음과 같습니다.

pip list --format=freeze > installed_packages.txt

또는 Python 스크립트를 사용할 수도 있습니다.

import pkg_resources

installed_packages = [d.project_name for d in pkg_resources.working_set]
print(installed_packages)

2. 알려진 취약점 데이터베이스와 비교

다음 단계는 설치된 모듈을 알려진 취약점 데이터베이스와 비교하는 것입니다. 이를 위해 여러 오픈 소스 도구를 사용할 수 있습니다. 예를 들어, Safety라는 도구는 Python 패키지의 취약점을 체크하는 데 사용할 수 있습니다.

pip install safety
safety check

이 명령은 설치된 모든 패키지를 체크하고, 알려진 취약점이 있는 패키지에 대해 경고합니다.

3. 알람 및 처리

악성 또는 취약한 패키지를 발견하면, 이에 대한 알람을 설정하고 적절한 조치를 취할 필요가 있습니다. 이는 스크립트나 자동화된 시스템을 통해 구현할 수 있습니다.

 

예를 들어, safety 또는 다른 도구의 출력을 파싱하여 알람을 보내는 스크립트를 작성할 수 있습니다. 이 스크립트는 이메일, SMS, 또는 다른 알람 시스템을 사용하여 경고를 보낼 수 있습니다. 또한, 자동으로 문제가 있는 모듈을 격리하거나 삭제하는 스크립트를 작성할 수 있습니다. 예를 들어, pip uninstall 명령을 사용하여 문제가 있는 패키지를 삭제할 수 있습니다.

import subprocess

def uninstall_package(package):
    subprocess.run(["pip", "uninstall", "-y", package])

uninstall_package("problematic-package")

4. 정기적인 검사 및 업데이트

보안은 지속적인 과정입니다. 정기적으로 Python 환경을 검사하고, 패키지를 최신 버전으로 유지하는 것이 중요합니다. 이를 위해 CRON 작업, 작업 스케줄러, 또는 CI/CD 파이프라인을 설정할 수 있습니다.

주의사항

  • 자동으로 패키지를 삭제하거나 격리하는 것은 위험할 수 있습니다. 이러한 작업은 충분한 테스트 후에 신중하게 진행해야 합니다.
  • 새로운 취약점은 지속적으로 발견되므로, 취약점 데이터베이스를 정기적으로 업데이트하는 것이 중요합니다.
  • 알람 시스템을 구축할 때는 오진(False Positives)과 오류(False Negatives)를 최소화하기 위한 전략이 필요합니다.
  • 보안 관련 작업을 수행할 때는 항상 데이터 백업과 복구 계획을 마련해 두는 것이 좋습니다.

 

Python 모듈의 설치, 업데이트 또는 제거와 같은 변동 사항을 감지하고 이러한 정보를 슬랙으로 알람하는 것은 자동화된 모니터링 시스템의 좋은 예입니다.

1. 슬랙 웹훅 설정

먼저 슬랙에서 웹훅을 설정해야 합니다. 이를 위해 슬랙 앱을 만들고, 해당 앱에 대한 웹훅 URL을 생성해야 합니다. 슬랙의 'Incoming WebHooks' 기능을 사용하여 이를 설정할 수 있습니다.

2. Python 스크립트 작성

Python 스크립트를 작성하여 설치된 모듈의 변경 사항을 감지하고, 이를 슬랙으로 전송합니다. 이 스크립트는 크게 두 부분으로 구성됩니다.

  1. 설치된 모듈의 변경 사항 감지: 이전과 현재의 모듈 리스트를 비교하여 변경 사항을 감지합니다.
  2. 변경 사항을 슬랙으로 전송: 감지된 변경 사항을 슬랙 웹훅을 통해 전송합니다.
import subprocess
import json
import requests

# 이전과 현재의 모듈 리스트를 가져오는 함수
def get_installed_packages():
    result = subprocess.run(["pip", "list", "--format=json"], capture_output=True, text=True)
    return {pkg["name"]: pkg["version"] for pkg in json.loads(result.stdout)}

# 모듈의 변경 사항을 감지하는 함수
def detect_changes(old_packages, new_packages):
    changes = []
    for pkg, ver in new_packages.items():
        if pkg not in old_packages:
            changes.append(f"Installed: {pkg}=={ver}")
        elif old_packages[pkg] != ver:
            changes.append(f"Updated: {pkg} {old_packages[pkg]} -> {ver}")
    for pkg in old_packages:
        if pkg not in new_packages:
            changes.append(f"Removed: {pkg}")
    return changes

# 슬랙에 메시지를 보내는 함수
def send_to_slack(message, webhook_url):
    payload = {"text": message}
    response = requests.post(webhook_url, json=payload)
    response.raise_for_status()

# 메인 로직
def main():
    webhook_url = "YOUR_SLACK_WEBHOOK_URL"  # 슬랙 웹훅 URL

    # 이전 모듈 리스트 로드 (예를 들어 파일에서)
    # 이 부분은 파일에서 로드하거나, 다른 방법으로 이전 상태를 가져옵니다.
    old_packages = {}  # 예시에서는 빈 사전으로 설정

    # 현재 모듈 리스트 가져오기
    new_packages = get_installed_packages()

    # 변경 사항 감지
    changes = detect_changes(old_packages, new_packages)

    # 변경 사항이 있으면 슬랙으로 전송
    if changes:
        send_to_slack("\n".join(changes), webhook_url)

if __name__ == "__main__":
    main()

3. 정기적 실행

이 스크립트를 정기적으로 실행하기 위해 CRON 작업(리눅스) 또는 작업 스케줄러(윈도우)를 설정할 수 있습니다.

주의사항

  • 슬랙 웹훅 URL은 민감한 정보이므로 안전하게 관리해야 합니다.
  • 이 스크립트는 변경 사항을 감지하기 위해 이전 상태를 어딘가에 저장해야 합니다. 예시에서는 이 부분을 간단하게 처리했으나, 실제 사용 시 파일 시스템, 데이터베이스 등을 사용하여 이전 상태를 관리할 수 있습니다.
  • 스크립트의 오류 처리를 위해 예외 처리 로직을 추가하는 것이 좋습니다.

 

pythonw는 콘솔 창이 없이 파이썬 스크립트를 실행하는 데 사용되는 실행 파일입니다. 일반적으로 pythonw를 사용하여 GUI 애플리케이션을 실행할 때 사용되며, 이 때 콘솔 창이 뜨지 않습니다. 그러나 pip와 같은 패키지 관리자를 사용할 때는 일반적으로 콘솔 창을 통해 이루어집니다.

 

그럼에도 불구하고, pythonw를 사용하여 pip 명령을 실행하고자 한다면, 이를 스크립트 파일 내에서 수행하는 방법을 사용할 수 있습니다. 아래는 pythonw를 사용하여 pip 명령을 실행하는 방법에 대한 예시입니다.

  1. 파이썬 스크립트 파일 생성: 파이썬 스크립트 파일을 생성합니다. 이 파일 안에 pip를 사용하는 코드를 작성합니다.
  2. pip 명령 실행 코드 작성: 스크립트 파일 내에서 subprocess 모듈을 사용하여 pip 명령을 실행합니다. 예를 들어, requests 패키지를 설치하고자 한다면 다음과 같은 코드를 작성할 수 있습니다.
     import subprocess
     import sys
    
     subprocess.check_call([sys.executable, "-m", "pip", "install", "requests"])
  3. 스크립트 실행: 생성한 스크립트 파일을 pythonw를 사용하여 실행합니다. 예를 들어, 스크립트 파일의 이름이 install_requests.py라면, 다음과 같은 명령을 사용합니다.
     pythonw install_requests.py

이 방법을 사용하면 콘솔 창이 뜨지 않고 pip 명령을 실행할 수 있습니다. 그러나 이 방법은 일반적인 pip 사용과 다르게 오류 메시지나 로그를 콘솔에서 직접 볼 수 없다는 단점이 있습니다. 따라서 문제 해결이 더 어려울 수 있으므로, 가능하다면 일반적인 방법으로 pip를 사용하는 것이 좋습니다.

728x90

댓글