fail2ban으로 공격자의 IP 차단하기 + Slack 연동

Asher·2025년 7월 21일

VPN

목록 보기
2/3
post-thumbnail

0. 도입

최근 한 기업이 랜섬웨어 공격으로 인해 업무에 큰 차질을 겪었다는 보안 기사를 접했습니다. 해킹 그룹이 Brute Force 기법을 이용해 SSL-VPN에 무차별 로그인 시도를 한 끝에 내부망을 장악한 것이 원인이었습니다. 이 기사를 보고 저희가 운영 중인 VPN도 동일한 위협에 노출될 수 있다는 우려가 생겼고, 이에 따라 로그인 시도를 제한하는 방안을 검토하게 되었습니다.

1. fail2ban이란?

  • Fail2Ban은 서버 보안을 강화하기 위해 널리 사용되는 침입 방지 도구(IPS, Intrusion Prevention System)입니다. 주로 SSH, FTP, SMTP, Apache, Nginx, VPN 등 외부 접근이 가능한 서비스에서 발생하는 비정상적인 로그인 시도를 자동으로 탐지하고 차단하는 데 사용합니다.

  • fail2ban의 주요 기능

    기능설명
    로그 분석/var/log/secure, /var/log/auth.log 등 로그 파일을 실시간 감시
    IP 차단공격으로 의심되는 IP를 iptables, firewalld, nftables, 또는 route 명령어로 차단
    다중 jail 지원각 서비스별로 감시 규칙(jail)을 개별 설정 가능
    차단 해제일정 시간이 지나면 자동으로 차단 해제 (또는 수동 해제 가능)
    Slack, 이메일 알림공격 탐지 시 관리자에게 알림 전송 가능

2. fail2ban 기본 환경 구성

  • fail2ban 설치
    apt-get install fail2ban -y
  • fail2ban 프로세스 시작
    systemctl enable fail2ban
    systemctl start fail2ban
  • fail2ban 프로세스 상태 확인
    systemctl status fail2ban.service

3. fail2ban 기본 구조

먼저 fail2ban의 기본 구조를 살펴 보겠습니다.
가장 중점적으로 볼 부분은

  • action.d/
    • 액션 정의 디렉토리
    • fail2ban이 특정 조건을 만족할 때 어떤 Action을 행할지 정의한 템플릿이 들어있는 폴더
    • iptables-common.conf, ufw.conf 등 다양한 템플릿이 기본적으로 내장되어 있음
  • filter.d/
    • 로그 필터 정의 디렉토리
    • 로그에서 공격을 탐지하기 위한 정규식 필터가 있는 폴더
    • sshd.conf, gitlab.conf 등 다양한 정규식 필터가 있음
  • jail.local
    • 사용자 정의 Jail 설정 파일
    • 기존에 설정되어 있는 jail.conf를 덮어쓰는 우선순의 파일(해당 파일은 생성해야함)

입니다. 이 3가지의 구조로 기본적인 IP 차단 룰을 구현 할 수 있기 때문에 나머지 부분은 참고해주시면 됩니다.

/etc/fail2ban
├── action.d/               # 액션 정의 파일들 (예: IP 차단 방식)
├── fail2ban.conf           # fail2ban 기본 설정 파일
├── fail2ban.d/             # fail2ban 설정 조각(디렉토리 override용)
├── filter.d/               # 로그 필터 정의 (regex 기반)
├── jail.conf               # 기본 jail 설정 파일
├── jail.d/                 # 개별 jail 설정 파일 모음
├── jail.local              # 사용자 정의 jail 설정 파일 (우선 적용됨)
├── paths-arch.conf         # Arch 리눅스용 로그 경로 설정
├── paths-common.conf       # 공통 로그 경로 설정
├── paths-debian.conf       # Debian 계열용 로그 경로 설정
├── paths-opensuse.conf     # OpenSUSE용 로그 경로 설정

4. VPN 환경에 fail2ban 적용

기존에 운영하던 VPN에 해당 프로세스를 적용한 뒤, 고도화로 내용으로 Slack과 연동을 진행해 보겠습니다
VPN 구축이 궁금하신 분은 아래의 링크 참고 부탁드립니다

VPN 서버 구축기

  • fail2ban 정책 생성

    cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
    • jail.local 파일 최하단에 VPN 내용 삽입
      [vpn]
      enabled = true
      filter = vpn-auth
      port = 1111
      protocol = udp   # 프로토콜 default는 TCP
      logpath = /var/log/로그경로.log 
      maxretry = 5     # 최대 시도 횟수
      bantime = 600    # 차단 시간
      findtime = 300   # 탐지 범위
      action = %(action_)s   # 차단 후 Action
             slack-notify
  • 기존 sshd fail2ban disable

    vi /etc/fail2ban/jaid.d/defaults-debian.conf
    [sshd]
    enabled = false

    sshd도 같이 차단 정책을 걸고 싶으면 해당 부분은 true로 설정하시면 됩니다.

  • 로그 포맷 설정

    vi /etc/fail2ban/filter.d/vpn-auth.conf
    [Definition]
    maxlines = 10
    
    prefregex = ^\s*(?:(?:[A-Za-z]{3}\s+\d+\s+\d{2}:\d{2}:\d{2}\s+[\w\d\.-]+\s+)?(?:vpn\[\d+\]:)?\s*)PLUGIN AUTH-PAM: BACKGROUND: user '(?P<user>[^']+)' failed to authenticate: Authentication failure
    
    failregex = ^(?:<F-NOFAIL>IP:Port SENT CONTROL \[UNDEF\]: 'AUTH_FAILED' \(status=1\)</F-NOFAIL>\s+)?<HOST>:\d+ SENT CONTROL \[UNDEF\]: 'AUTH_FAILED' \(status=1\)$
    
    ignoreregex =
    
    • prefregex
      • 로그 메시지 앞부분의 공통된 패턴을 정의하기 위한 정규식
    • failregex
      • 차단 대상이 되는 로그 메시지를 감지하기 위한 정규식
      • 해당 정규식에 매칭되는 로그가 탐지되면, fail2ban은 해당 로그의 IP를 추출하여 차단 대상으로 지정
    • ignoreregex
      • 예외 처리 패턴, 무시할 로그 패턴

    저는 로그인을 시도한 IP와 user명을 Slack으로 알림 보내기 위해 failregex와 같이 prefregex를 사용하였습니다. 각 환경에 맞게 정규식을 조정하시면 됩니다.

  • IP 차단 후 Action 설정 편집

    vi /etc/fail2ban/action.d/slack-notify.conf
    [Definition]
    actionstart =
    actionstop =
    actioncheck =
    
    # 'actionban'은 IP가 차단될 때 실행될 명령어
    # 스크립트에 다음 인자들을 전달합니다:
    # 1. <ip>: 차단될 IP 주소 (Fail2Ban이 자동으로 제공)
    # 2. BANNED: 조치 타입
    # 3. <name>: 조치를 유발한 Jail 이름 (Fail2Ban이 자동으로 제공)
    # 4. <F-USER>: 필터에서 캡처된 사용자 ID
    actionban = /etc/fail2ban/slack-notify.sh <ip> BANNED <name> <F-USER>
    
    # 'actionunban'은 IP 차단이 해제될 때 실행될 명령어
    # 동일한 인자들을 전달합니다.
    actionunban = /etc/fail2ban/slack-notify.sh <ip> UNBANNED <name> <F-USER>
  • Slack 알림 스크립트 생성

    vi /etc/fail2ban/slack-notify.sh
    #!/bin/bash
    # Slack 웹훅 URL WEBHOOK_URL="https://hooks.slack.com/test" # 이 부분을 본인의 웹훅 URL로 변경해주세요!
    # Fail2Ban으로부터 전달받는 인자들
    HOST="$1"    # 차단되거나 해제된 IP 주소 (Fail2Ban이 차단하는 대상)
    ACTION="$2"  # 'BANNED' 또는 'UNBANNED'
    JAIL="$3"    # 조치가 발생한 Fail2Ban Jail 이름
    USERID="$4"  # 필터에서 캡처된 사용자 ID
    
    # Slack 알림을 보낼 채널 설정
    CHANNEL="#test" 
    
    if [[ "$ACTION" == "BANNED" ]]; then
      COLOR="#ff0000"
    elif [[ "$ACTION" == "UNBANNED" ]]; then
      COLOR="#36a64f"
    else
      COLOR="#cccccc"
    fi
    
    # 메시지 내용
    TEXT="*IP 차단 알림*
    *조치:* ${ACTION}
    *IP 주소:* ${HOST}
    *사용자 ID:* ${USERID}
    *시간:* $(date +'%Y-%m-%d %H:%M:%S %Z')"
    
    # JSON 페이로드 생성
    PAYLOAD=$(cat <<EOF
    {
      "channel": "${CHANNEL}",
      "username": "test",
      "icon_emoji": ":happy:",
      "attachments": [
        {
          "color": "${COLOR}",
          "text": "${TEXT}"
        }
      ]
    }
    EOF
    )
    
    # Slack으로 메시지 전송
    curl -X POST -H "Content-type: application/json" --data "${PAYLOAD}" "${WEBHOOK_URL}"
  • fail2ban 재시작 및 로그 확인

    systemctl restart fail2ban.service
    tail -50 /var/log/fail2ban.log

  • Jail List 확인

    fail2ban-client status

  • IP 차단 테스트

fail2ban-client status {JAIL-NAME}

  • 차단 되었을 경우

  • 차단 해제

    fail2ban-client set <jail-name> unbanip <IP>

profile
System Engineer의 발전기록

0개의 댓글