분석 · 관제핵심 · 17분 읽기
Fail2ban: 실패 로그에서 방화벽 차단까지
Rocky Linux 9의 SSH 실습을 바탕으로 backend·filter·jail·action, 시간 창과 차단 기간, 실제 규칙 검증 및 오탐 해제를 연결합니다.
개념부터 찾아보기
정의·역할·동작 원리를 독립 페이지에서 확인하세요. 본문의 밑줄 용어에도 설명이 있습니다.
이 노트에서 설명할 수 있게 되는 것
- backend·filter·jail·action의 역할과 실패 지점을 구분한다.
- 시간 창과 차단 기간을 로그 사건에 적용한다.
- jail 상태와 실제 방화벽 동작을 대조한다.
01개념과 구성 요소
- 탐지 입력파일 또는 journal에서 서비스의 실패 기록을 읽는다.
- Backend··임계값·action을 묶어 어떤 기록을 어떤 대응으로 연결할지 정한다.
- 차단의 실체의 Ban 상태와 방화벽의 실제 패킷 경로를 함께 확인해야 차단 효과를 알 수 있다.
02실패 로그가 일시 차단으로 이어지는 순서
- 로그 수신Backend가 파일 위치 또는 journalmatch에 맞는 기록을 읽는다.
- 패턴·주소 추출가 신뢰할 수 있는 실패 패턴에서 대응할 주소를 추출한다. 사용자 문자열을 주소로 오인하면 오차단이 된다.
- 시간창 집계같은 대상의 일치 기록을 안에서 세어 조건을 평가한다. 기록 수는 사람의 시도 횟수와 같지 않을 수 있다.
- Ban Action설정된 action이 방화벽 등에 규칙을 반영한다. 논리적 Ban만으로 ·와 모든 통신 경로가 막히는 것은 아니다.
- 만료·해제 또는 관리자의 해제에 따라 규칙을 제거하고 예외·오탐·재발 상태를 확인한다.
03탐지와 차단을 연결하는 구성 요소
- 로그 기반 탐지은 인증 서버 앞에서 모든 패킷의 비밀번호를 검사하는 장비가 아니다. 서비스가 남긴 실패 로그를 backend가 읽고 가 정해진 패턴으로 사건과 주소를 추출한다.
- 은 어떤 서비스·입력·필터·시간 조건·action을 묶을지 정하며, 조건에 도달하면 action이 방화벽 등의 조치를 수행한다.
- Backend·Action로그가 남지 않거나 backend가 해당 로그를 읽지 못하면 차단 조건을 평가할 근거가 없다. 필터가 사건을 찾았더라도 action이 실패하면 실제 패킷이 막히지 않는다.
- 차단 범위설치, 서비스 실행, 활성화, 실패 탐지, ban 상태, 실제 방화벽 적용을 서로 다른 확인 지점으로 둔다.
- 실습 구성원본 실습은 9에서 SSH 실패를 journal로 읽고 와 연계하는 구성이었다. 배포판의 기본 action과 서비스 이름은 패키지에 따라 달라지므로 실제 적용 설정과 실행 결과를 함께 읽는다.
04systemd backend와 파일 backend의 차이
- Journal 입력 backend는 journal의 필드와 journalmatch 조건으로 대상 이벤트를 읽는다. 파일 경로를 tail하는 방식이 아니므로 같은 에 logpath를 넣어 그것이 journal 입력을 지정한다고 생각하면 안 된다.
- 문맥필터가 기대하는 journal 필드와 실제 sshd 기록이 일치하는지 확인한다.
- 파일 입력파일 backend는 지정한 로그 경로를 읽고 파일 회전·권한·날짜 형식의 영향을 받는다. 설정에 따라 /var/log/secure 또는 다른 위치에 기록될 수 있으므로 배포판 이름만 보고 경로를 확정하지 않는다.
- 중계 환경별도 컨테이너나 중앙 로그 수집기를 사용하는 환경은 주소와 시간 필드 변형도 고려한다.
- 시간 파싱로그 시각을 잘못 해석하면 오래된 실패가 최근 것으로 잡히거나 현재 실패가 시간 창 밖으로 빠질 수 있다. 서버의 시간대·시계 동기화, parser가 해석한 시각을 확인한다.
- 입력 경계재시작 뒤 journal 커서나 저장 상태의 영향도 로그에서 검증한다.
05maxretry·findtime·bantime을 시간 축으로 읽기
- ·는 구간 안에서 해당 주소에 대해 필터가 집계한 실패 사건의 임계값이다. =5, =10m이면 10분 안에 매칭되는 실패 기록이 5개 쌓일 때 차단 조건이 된다.
- 시도와 기록실제 사용자가 입력한 비밀번호 횟수와 로그 매칭 수가 항상 같지는 않다. 한 시도에서 여러 실패 행이 생기거나 필터가 일부만 세는 경우가 있다.
- =10m은 차단 후 유지할 기간이다. 과 목적이 다르다.
- 시간창 예설명용으로 같은 IP의 실패가 09:00, 09:02, 09:04, 09:06, 09:08에 들어오면 다섯 번째에서 조건에 도달한다. 09:00의 실패 한 건만 있고 다음 실패가 09:20이라면 이전 건은 그 10분 창 밖이다.
- 미탐·오탐많은 사용자가 뒤에서 같은 출발지 IP를 공유하면 한 사람의 반복 실패가 다른 사용자에게도 영향을 줄 수 있다. 반대로 여러 IP가 느리게 시도하면 주소별 임계값을 넘지 않을 수 있다.
- 정책 목적차단 정책은 MFA·키 기반 인증·접근 범위 제한을 보완하며 전체 계정 보안을 대신하지 않는다.
ini
[sshd]
enabled = true
backend = systemd
port = ssh
maxretry = 5
findtime = 10m
bantime = 10m수업의 핵심 설정을 재구성한 예제. action과 journalmatch는 설치된 기본값을 포함해 실제 적용 결과를 확인해야 한다.
원리 심화
06Jail의 이벤트 집계와 방화벽 상태의 분리
- 매칭 단위은 에 일치하고 주소·시각을 추출한 실패 레코드를 집계한다. 한 로그인 시도가 로그 여러 줄을 만들면 사람의 시도 수와 다를 수 있다.
- 시간 창은 실패를 모으는 구간, 는 차단 판단의 횟수 조건, 은 차단 기간에 관련된다. 세 값을 같은 시간 제한으로 해석하지 않는다.
- 논리 상태이 주소를 Ban 상태로 기록하는 것과 action 명령이 실제 네트워크 경로에 적용되는 것은 별도 단계다.
- 주소별 상태같은 안에서도 추출 주소별 이력이 다르다. 뒤 여러 사용자가 하나의 주소로 집계되면 업무 영향이 함께 발생할 수 있다.
- 복구 상태 재시작·저장 DB·방화벽 reload 이후 논리 Ban과 실제 규칙이 일치하는지 확인한다. 설정 파일 존재는 런타임 적용 증거가 아니다.
예제로 추적
07가상 한 번의 로그인에서 네 줄이 발생한 사례
- 시험 조건=5·=10분이고 주소 A의 이력이 비어 있다고 가정한다. 한 동작이 필터에 맞는 네 레코드를 생성했다.
- 첫 동작 집계필터가 네 레코드를 모두 실패로 인정하면 카운터는 4다. 사용자가 한 번 입력했다는 사실과 집계 단위가 다르다.
- 다음 레코드같은 주소에서 10분 안에 일치 레코드 하나가 추가되면 5에 도달하여 설정된 차단 조건을 만족한다.
- 다른 주소주소 B의 레코드는 A의 이력에 더하지 않는다. 주소 추출이 잘못되면 이 분리가 깨질 수 있다.
- 실제 효과Ban 로그 뒤 action 성공·규칙 존재·새 연결의 처리 결과를 따로 확인한다. 이미 성립한 연결과 새 연결의 영향이 같다고 가정하지 않는다.
검증·예외
08차단이 안 되거나 정상 사용자가 차단될 때
- 로그 원천 backend의 journalmatch와 파일 backend의 경로를 혼동하지 않았는지 본다. 가 맞아도 다른 로그를 읽으면 이력이 쌓이지 않는다.
- 시각 파싱레코드의 시각·시간대·서버 현재 시각이 맞는지 확인한다. 오래된 것으로 판단된 레코드가 밖으로 빠질 수 있다.
- 주소 신뢰사용자가 조작할 수 있는 본문 문자열을 신뢰 주소처럼 추출하지 않는다. 프록시 앞뒤에서 어느 주소를 차단해야 하는지도 명시한다.
- Action 경로방화벽 제품·chain·인터페이스·/·관리 권한을 비교한다. 의 Ban 수만으로 실제 차단 경로를 확정하지 않는다.
09filter: 신뢰할 주소를 정확히 추출하기
- 주소 추출는 로그에서 실패 사건과 호스트 주소를 찾아야 한다. 사용자가 임의로 입력할 수 있는 사용자명이나 URL을 주소처럼 추출하면 공격자가 다른 사람의 주소를 문자열에 넣어 오차단을 유도할 수 있다.
- 신뢰 필드서비스가 보증하는 로그 접두부와 실제 출발지 필드에 패턴을 고정한다.
- 검증정상 로그인, 잘못된 사용자명, ·, 다른 메시지 형식이 섞인 표본으로 매칭과 비매칭을 함께 확인한다. 이 몇 줄을 찾았다는 결과만으로 정상 사용자를 차단하지 않는다고 단정할 수 없다.
- 로그 형식 변경버전 변경 뒤 로그 문구가 바뀌면 기존 필터가 조용히 탐지를 놓칠 수 있다.
- Proxy 주소나 중계 서버를 거치면 로그에 중계 주소가 남을 수 있다. 실제 클라이언트 주소는 신뢰한 프록시가 검증해서 전달한 필드에서 얻어야 한다.
- 헤더 신뢰클라이언트가 임의로 보낸 X-Forwarded-For 전체를 신뢰해 방화벽 차단 주소로 쓰지 않는다.
10action: 논리적 Ban과 실제 패킷 경로
- 방화벽 연결action은 Ban/Unban 시점에 방화벽 규칙 등을 적용한다. status에 IP가 있다는 사실과 패킷이 실제 차단 체인을 통과한다는 사실은 다르다.
- Action 문맥선택한 action이 ··iptables 중 무엇을 사용하는지, SSH 포트와 를 포함하는지 확인한다.
- 프로토콜 범위서비스 포트가 22가 아닌데 action이 기본 ssh만 막으면 원하는 접속은 계속 통과할 수 있다. 컨테이너·포워딩 경로·다른 네트워크 namespace는 호스트 INPUT 규칙과 다른 경로를 지날 수 있다.
- 기존 연결이미 성립된 연결의 처리는 conntrack과 규칙 순서에 따라 달라 신규 차단과 구분한다.
- Ban 검증 reload나 다른 자동화가 runtime 규칙을 바꾸면 차단 상태와 실제 방화벽이 어긋날 수 있다. 전용 규칙을 확인하고 문제를 고칠 때 시스템의 모든 방화벽 규칙을 초기화하지 않는다.
- 허용 경로전체 방화벽의 상시 접근 제어와 일시적 ban 규칙을 분리해 운영한다.
11Ban 상태와 오류 메시지 해석
- 원본 관찰실습에서는 Server ready, sshd 활성화, 시험 클라이언트의 차단 상태와 f2b-sshd 관련 규칙을 확인했다. 이 관찰만으로 모든 재부팅·reload 이후의 정책 지속성을 입증한 것은 아니다.
- 255/EXCEPTION255/EXCEPTION 표기만으로 오류 원인을 하나로 확정할 수 없다. 잘못된 설정 경로, action 의존성, 문법과 로그 입력 문제를 실제 앞뒤 오류 메시지로 좁혀야 한다.
- 정상화 판단정상화 여부는 수정 후 실제 상태와 로그로 판단한다.
- 시험 범위교육용 반복 로그인 시험은 본인의 격리된 SSH 서버와 회복용 콘솔에서 수행해야 한다. 문서의 숫자는 정책 작동을 설명하기 위한 예제이며 현재 사용자의 서버에 차단을 실행한 결과가 아니다.
12상태·탐지·규칙을 각각 검증하기
- 상태-client status는 활성 목록을, status sshd는 해당 의 탐지·차단 집계를 보여 준다. journal에서 Found와 Ban을 구분하고 action 실행 오류를 함께 읽는다.
- Found·BanFound는 필터가 사건을 찾았다는 뜻이며 그 한 줄만으로 차단이 이루어졌다고 결론 내리지 않는다.
- 실제 규칙실제 규칙을 읽어 출발지 주소·프로토콜·목적지 포트·체인 연결을 확인한다. action 종류에 맞는 관리 도구를 사용하고 nft 규칙이 보인다는 이유만으로 iptables 호환 계층의 관계를 무시하지 않는다.
- 시험 위치허가된 시험 클라이언트에서 신규 접속 결과를 대조하면 정책 적용 여부를 더 확실히 확인할 수 있다.
shell
fail2ban-client status
fail2ban-client status sshd
fail2ban-client get sshd maxretry
fail2ban-client get sshd findtime
fail2ban-client get sshd bantime
fail2ban-client get sshd actions
journalctl -u fail2ban --since "10 minutes ago"
nft list ruleset상태와 규칙을 읽는 예제. 해당 시스템의 권한과 실제 action을 전제로 하며 이 사이트에서 실행하지 않는다.
LEARN THROUGH PRACTICE
SSH 실패 로그에서 Jail 집계와 실제 차단까지
주석 처리된 설정, 실행 중인 통계, 방화벽 action을 구분하여 차단 동작의 증거를 읽는다.
실습 구성과 전제
- 자신의 격리 SSH 서버에서 관리 접속을 복구할 콘솔과 정상 접속원을 준비한다.
- 그림은 설정 설명과 실행 상태를 비교한 자료다. 보이는 통계를 특정 시험 횟수와 자동으로 같다고 간주하지 않는다.
설정 설명과 활성 Jail을 구분하기
- 설정 행 앞의 #은 주석이다. 예제에 enabled=true라는 글자가 있더라도 주석이면 그 행 자체가 을 활성화하지 않는다.
- 실제로 적용된 값은 .local 덮어쓰기와 다른 설정 파일을 합친 결과다. 배포본 파일의 한 부분만 보는 대신 실행 중인 목록과 ··을 조회한다.
bashsudo fail2ban-client status sshd sudo fail2ban-client get sshd maxretry sudo fail2ban-client get sshd findtime sudo fail2ban-client get sshd bantime실행 중인 의 상태와 시간 조건을 조회하는 예. 인증 실패 트래픽을 생성하지 않는다.
원본 크기로 보기 ↗- # [sshd]와 # enabled = true 앞에 주석 기호가 보인다. 이 두 줄만으로 sshd Jail이 켜졌다고 판단할 수 없다.
- 주석 옆에는 enabled와 filter 등의 역할을 설명하는 메모가 있다. 옵션 설명과 현재 유효 설정을 구분해 읽어야 한다.
확인 기준sshd 이 목록에 있고 유효 설정이 의도한 값인지 확인한다. 설정 파일 수정 후에는 문법 검사와 해당 재적용이 필요하다.
로그 일치 건수와 차단 건수를 나누어 읽기
- 가 로그에서 뽑아낸 주소별 실패 이벤트를 범위에서 집계한다. 한 번의 로그인 시도에서 여러 줄이 발생할 수 있으므로 Total failed를 사람이 입력한 비밀번호 횟수와 동일시하지 않는다.
- backend는 journalmatch로 저널 항목을 고른다. 서비스 이름과 프로그램 이름이 실제 로그와 다르면 파일이 존재해도 이 에 이벤트가 들어오지 않을 수 있다.
원본 크기로 보기 ↗- 상태 출력은 Currently failed 1, Total failed 12와 Currently banned 1, Total banned 1을 별도 구역에 표시한다.
- Journal matches에 sshd.service와 sshd·sshd-session 조건이 보인다. 파일 경로 하나를 tail하는 방식과 입력 선택 조건이 다르다.
확인 기준같은 시간대의 인증 로그·Found·Ban 사건을 대응시킨다. 통계가 증가했어도 현재 차단 주소와 시험 주소가 같은지는 별도 확인한다.
action에서 실제 패킷 경로로 내려가기
- action_은 banaction 이름을 참조하고, action_mw는 여기에 메일 보고 동작 등을 묶는다. 템플릿에 적힌 이름만으로 실제 방화벽 백엔드를 iptables라고 고정하면 안 된다.
- 내부의 Ban 상태와 커널의 차단 규칙은 서로 다른 확인 지점이다. 설치 환경의 action과 규칙을 읽고, 시험 접속원의 접근 제한과 정상 접속원의 유지 여부를 함께 검증한다.
bashsudo fail2ban-client get sshd actions sudo journalctl -u fail2ban --since '-10 min' --no-pager선택된 action과 최근 서비스 기록을 조회한다. 운영 주소나 인증 비밀을 결과 보고서에 복사하지 않는다.
원본 크기로 보기 ↗- action_ 정의가 %(banaction)s를 참조하므로 실제 실행할 차단 방식은 치환된 설정에 달려 있다.
- action_mw는 차단 템플릿 다음에 메일 관련 동작을 붙인다. 알림 발송과 패킷 차단이 하나의 성공 조건은 아니다.
확인 기준자동 해제 시간이 지난 뒤 상태와 방화벽 규칙이 함께 해제되는지도 확인한다. 규칙만 사라졌다면 방화벽 reload와 action 오류를 조사한다.
실습에서 확인한 동작 원리
- 설정 설명→유효 →로그 일치→Ban 상태→방화벽 규칙→접속 결과를 순서대로 연결한다.
- 실패 로그 수, 로그인 시도 수, 고유 주소 수는 서로 다른 지표다.
설정·출력 추가로 확인하기 9장
아래 화면을 펼쳐 위 실습의 설정값, 명령과 확인 기준을 비교해 보세요. 각 묶음은 별도 실습 기록입니다.
실습 화면 묶음 01 1장
원본 크기로 보기 ↗- 에 삽입된 원본 학습 화면이다. Fail2ban의 filter.d 디렉터리에 들어 있는 서비스별 로그 필터 설정 파일 목록을 확인하는 화면이다.
실습 화면 묶음 02 1장
원본 크기로 보기 ↗- 학습 원본 · Fail2ban 탐지·차단 설정과 상태의 fail2ban에 수록된 화면·도식이다.
실습 화면 묶음 03 1장
원본 크기로 보기 ↗- 학습 원본 · Fail2ban 탐지·차단 설정과 상태의 fail2ban에 수록된 화면·도식이다.
실습 화면 묶음 04 1장
원본 크기로 보기 ↗- 학습 원본 · Fail2ban 탐지·차단 설정과 상태의 fail2ban에 수록된 화면·도식이다.
실습 화면 묶음 05 1장
원본 크기로 보기 ↗- 학습 원본 · Fail2ban 탐지·차단 설정과 상태의 fail2ban에 수록된 화면·도식이다.
실습 화면 묶음 06 1장
원본 크기로 보기 ↗- 학습 원본 · 원격 로그인 반복 시도와 차단 검증의 IPBan에 수록된 화면·도식이다.
실습 화면 묶음 07 1장
원본 크기로 보기 ↗- 학습 원본 · 원격 로그인 반복 시도와 차단 검증의 IPBan에 수록된 화면·도식이다.
실습 화면 묶음 08 1장
원본 크기로 보기 ↗- 학습 원본 · 원격 로그인 반복 시도와 차단 검증의 dnf install freerdp -y에 수록된 화면·도식이다.
실습 화면 묶음 09 1장
원본 크기로 보기 ↗- 학습 원본 · 원격 로그인 반복 시도와 차단 검증의 dnf install freerdp -y에 수록된 화면·도식이다.
동작·명령 참고 문서
13오탐 해제와 설정을 재현 가능하게 유지하기
- Local 설정공급자 기본 .conf를 직접 고치기보다 .d의 별도 파일이나 적절한 local override로 변경 이유와 적용 범위를 남긴다. 변경 전 파일을 보관하고 설정 검증 후 해당 서비스 상태를 확인한다.
- 버전 관리자동화는 입력값 검증·원자적 파일 교체·실패 시 해당 변경만 복구하는 절차를 갖춘다.
- 복구·IgnoreIP관리자 회복용 경로와 필요한 ignoreip는 최소 범위로 정한다. 광범위한 사설 대역 전체를 예외 처리하면 내부에서 발생한 공격을 놓칠 수 있다.
- 개별 해제개별 주소의 오탐을 해제한 뒤에도 필터 오인식·공유 ·시각 오류라는 원인을 고치지 않으면 다시 차단된다.
- 재현 조건배포 완료 기준은 설치 성공 메시지가 아니라 올바른 로그 입력, 기대한 사건 집계, 정확한 포트·주소 차단, 기간 뒤 해제, 서비스 재시작과 방화벽 reload 뒤의 일관성이다. 이 결과를 사건 시각과 함께 남겨야 다음 운영자가 같은 정책을 검증할 수 있다.
학습 확인
이해했는지 확인하기
- 로그 백엔드·필터·실패 횟수·시간 조건이 맞는지 확인한다.
- 탐지 기록과 실제 방화벽 차단 효과를 각각 확인한다.
- 공유 주소 오차단과 해제·복구 경로를 점검한다.