Haru Utils

보안 · 구성 레시피

Fail2ban·UFW·firewalld 안전 연동

현재 배포판이 관리하는 단일 방화벽을 유지하면서 Fail2ban SSH jail을 추가하고, 관리자 잠금 방지·로그 매칭·설정 검사·긴급 unban을 순서대로 검증합니다.
Fail2ban 설치SSH brute forceUFW Fail2banfirewalld Fail2banSSH 잠금 복구
지원 환경Ubuntu Server 24.04 LTS와 UFW 또는 배포판 기본 nftables 동작
예상 시간40
난이도고급
검토일2026-08-28

BEFORE YOU START

시작 전에 준비하세요

01

콘솔 접근 수단, 현재 SSH 세션, 공개키 전용 두 번째 관리자 세션

02

실제 SSH 포트와 승인된 관리자 IPv4 CIDR

03

현재 UFW·firewalld·nftables 중 규칙 소유자를 확인한 기록

04

상위 보안그룹에서 SSH를 관리자 CIDR로 제한한 상태

권장 대상 기존 SSH 접근 정책을 유지하면서 반복 인증 실패를 임시 차단하려는 Linux 서버 운영자

FOLLOW THE RECIPE

8단계 구성·점검 레시피

1
확인시스템을 변경하지 않는 점검 단계

배포판과 방화벽 소유자 확인

UFW와 firewalld를 동시에 활성화하지 않습니다. 현재 배포판 기본과 실제 활성 규칙 관리자를 먼저 판별합니다.

배포판
cat /etc/os-release
SSH 실제 설정
sudo sshd -T | grep -E '^(port|pubkeyauthentication|passwordauthentication|kbdinteractiveauthentication) '
UFW 상태
sudo ufw status verbose
firewalld 상태
sudo firewall-cmd --state
sudo firewall-cmd --get-active-zones
  • UFW 또는 firewalld 한 계층만 호스트 방화벽을 관리한다.
  • 실제 SSH 포트와 관리자 CIDR을 확인했다.
  • 콘솔과 두 번째 공개키 SSH 세션을 유지한다.
결과 읽기

두 방화벽이 모두 규칙을 관리하거나 직접 nft 규칙과 충돌하면 Fail2ban 설치보다 방화벽 소유권을 먼저 정리합니다.

다음 판단

인증 로그와 기존 Fail2ban·ban 규칙을 조사합니다.

2
확인시스템을 변경하지 않는 점검 단계

인증 로그·기존 jail·관리자 경로 점검

Fail2ban은 로그에 실제 실패 이벤트가 있어야 동작합니다. 비밀번호 로그인을 새로 허용해 시험하지 않고 기존 journal을 읽기 전용으로 확인합니다.

SSH journal
sudo journalctl -u ssh.service -u sshd.service --since '-1 hour' --no-pager
기존 Fail2ban
fail2ban-client --version
systemctl status fail2ban.service --no-pager
기존 jail 파일
sudo find /etc/fail2ban -maxdepth 2 -type f -name '*.local' -print
현재 공개키 세션
printf '%s\n' "$SSH_CONNECTION"
who
관리자 IP가 포함되므로 외부에 공유하지 않습니다.
  • SSH 인증 실패가 journal에 기록된다.
  • 관리자 CIDR과 현재 접속 출발지 주소를 대조했다.
  • 기존 jail과 사용자 정의 action의 소유 팀을 확인했다.
결과 읽기

journal에 이벤트가 없으면 backend를 억지로 켜지 말고 OpenSSH unit 이름과 로깅 경로를 먼저 확인합니다.

다음 판단

배포판에 맞는 한 가지 패키지 경로로 설치합니다.

3
변경패키지·설정·서비스 상태가 달라지는 단계

배포판 패키지로 Fail2ban 설치

Ubuntu와 Rocky 명령 중 현재 배포판에 맞는 한 분기만 사용합니다. Rocky는 조직이 승인한 저장소에 후보 패키지가 있을 때만 진행합니다.

변경 단계입니다. 대상 서버, 백업 파일, 서비스 중단 영향과 바로 이전 상태로 돌아가는 방법을 다시 확인하세요.
Ubuntu 인덱스
sudo apt update
Ubuntu 변경 미리 보기
apt-get --simulate install fail2ban python3-systemd
Ubuntu 설치
sudo apt-get install fail2ban python3-systemd
Rocky 후보 확인
sudo dnf info fail2ban
후보의 저장소와 서명을 조직 정책으로 승인한 경우에만 다음 명령을 사용합니다.
Rocky 설치
sudo dnf install fail2ban
설치 버전
fail2ban-client --version
  • 현재 배포판에 맞는 한 설치 분기만 사용했다.
  • 패키지 출처와 서명 정책을 확인했다.
  • 설치 직후 기존 방화벽을 비활성화하거나 교체하지 않았다.
결과 읽기

후보 패키지가 없으면 임의 설치 스크립트를 사용하지 말고 공식 배포판 또는 승인된 저장소 절차를 마련합니다.

다음 판단

배포판 기본 action을 유지한 최소 SSH jail을 작성합니다.

4
주의권한·연결·중단 영향을 확인할 단계

관리자 예외와 systemd backend 구성

패키지의 jail.conf를 수정하지 않고 .local 파일을 추가합니다. banaction을 임의로 강제하지 않아 배포판이 선택한 nftables·UFW·firewalld 통합을 중복 관리하지 않습니다.

백업 접미사
date -u +%Y%m%dT%H%M%SZ
기존 SSH jail 백업
sudo cp --preserve=all --no-clobber /etc/fail2ban/jail.d/sshd.local /etc/fail2ban/jail.d/sshd.local.<BACKUP_SUFFIX>.bak
기존 파일이 있을 때만 실행합니다.
SSH jail 편집
sudoedit /etc/fail2ban/jail.d/sshd.local
설정 전체 검사
sudo fail2ban-client -t
SSH 필터와 journal 사전 검사
sudo fail2ban-regex systemd-journal sshd --journalmatch='_SYSTEMD_UNIT=ssh.service + _SYSTEMD_UNIT=sshd.service'
기존 journal만 읽으며 실패 로그가 없으면 0 matches일 수 있습니다. 임의 로그인 실패를 만들지 않습니다.
설정 예시 · /etc/fail2ban/jail.d/sshd.local
보수적인 SSH jail
[sshd]
enabled = true
backend = systemd
port = <SSH_PORT>
mode = normal
findtime = 10m
maxretry = 5
bantime = 10m
ignoreip = 127.0.0.1/8 ::1 <ADMIN_IPV4_CIDR>
<ADMIN_IPV4_CIDR>는 실제 승인된 관리망만 사용합니다. banaction은 배포판 기본값을 따르며 UFW와 firewalld action을 동시에 지정하지 않습니다.
  • 배포판 jail.conf를 직접 수정하지 않았다.
  • ignoreip에 실제 관리자 CIDR과 루프백만 있다.
  • 실제 SSH 포트가 일치한다.
  • banaction을 중복 지정하지 않았다.
결과 읽기

fail2ban-client -t가 실패하면 서비스를 시작하지 말고 첫 오류 파일과 옵션을 수정합니다.

다음 판단

기존 세션을 유지한 채 설정 검사 성공 후 서비스를 시작합니다.

5
주의권한·연결·중단 영향을 확인할 단계

설정 검사 후 서비스 시작

관리자 CIDR 예외와 콘솔을 확인한 뒤 시작합니다. 공개키 인증 실패를 의도적으로 반복해 시험하지 않습니다.

최종 설정 검사와 시작
sudo fail2ban-client -t && sudo systemctl enable --now fail2ban.service && sudo fail2ban-client reload
서비스 상태
systemctl status fail2ban.service --no-pager
sudo journalctl -u fail2ban.service -n 100 --no-pager
jail 목록
sudo fail2ban-client status
SSH jail 상태
sudo fail2ban-client status sshd
  • 설정 검사·시작·reload가 &&로 연결돼 신규 jail이 실제 반영됐다.
  • sshd jail이 표시되고 오류 로그가 없다.
  • 기존 세션과 공개키 두 번째 세션이 유지된다.
결과 읽기

서비스는 active지만 sshd jail이 없으면 파일 로딩 순서·enabled·backend 오류를 확인합니다.

다음 판단

로그 매칭과 Fail2ban이 만든 규칙을 읽기 전용으로 검증합니다.

6
확인시스템을 변경하지 않는 점검 단계

jail·로그·방화벽 동작 검증

실제 공격 로그가 발생할 때 카운터가 증가하는지 관찰합니다. 관리자 주소에서 실패 로그를 생성하는 방식은 사용하지 않습니다.

SSH jail 상세
sudo fail2ban-client status sshd
유효 ignoreip
sudo fail2ban-client get sshd ignoreip
유효 action
sudo fail2ban-client get sshd actions
최근 Fail2ban 로그
sudo journalctl -u fail2ban.service --since '-30 minutes' --no-pager
  • 관리자 CIDR이 ignoreip에 정확히 반영됐다.
  • 현재 배포판 방화벽과 호환되는 단일 action만 사용한다.
  • 운영에서 자연 발생한 실패 이벤트가 있다면 failed 카운터가 증가한다.
결과 읽기

필터 카운터는 증가하지만 ban이 없다면 임계값·action을, 카운터가 0이면 journal match와 OpenSSH 로그를 확인합니다.

다음 판단

SSH 잠금 복구와 방화벽 중복 여부를 최종 점검합니다.

7
주의권한·연결·중단 영향을 확인할 단계

잠금 방지와 방화벽 단일 소유 점검

Fail2ban은 상위 CIDR 제한과 공개키 인증을 대체하지 않습니다. 차단 규칙을 추가하는 주체가 하나인지 확인합니다.

UFW 규칙
sudo ufw status numbered
firewalld 규칙
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --list-all
Fail2ban 차단 목록
sudo fail2ban-client status sshd
공개키 전용 새 세션
ssh -o PreferredAuthentications=publickey -o PasswordAuthentication=no -o KbdInteractiveAuthentication=no -t <ADMIN_USER>@<SERVER_IP> 'id && sudo -v'
현재 세션을 닫지 않은 채 승인된 관리자 CIDR에서 실행합니다.
  • UFW와 firewalld를 동시에 운영하지 않는다.
  • 상위 보안그룹이 SSH를 관리자 CIDR로 제한한다.
  • 공개키 전용 새 SSH 세션과 sudo가 성공한다.
  • 긴급 unban 명령과 콘솔 경로를 운영 문서에 남겼다.
  • 영구 ban보다 짧은 초기 bantime으로 오탐을 관찰한다.
결과 읽기

관리자 세션이 실패하면 기존 세션을 닫지 말고 ignoreip·실제 출발지 CIDR·차단 목록부터 복구합니다.

다음 판단

오탐이나 잠금 시 해당 IP만 unban하고 신규 jail 파일을 비활성화합니다.

8
주의권한·연결·중단 영향을 확인할 단계

긴급 unban과 jail 원복

콘솔 또는 살아 있는 기존 세션에서 정확한 클라이언트 IP만 unban합니다. 신규 파일을 삭제하지 않고 비활성화하고, 이전 백업이 있을 때만 복원합니다.

현재 ban 목록
sudo fail2ban-client status sshd
정확한 관리자 IP만 unban
sudo fail2ban-client set sshd unbanip <ADMIN_CLIENT_IP>
콘솔 또는 유지 중인 기존 세션에서 실제 관리자 IP를 확인한 뒤 실행합니다.
신규 jail 비활성화
sudo mv /etc/fail2ban/jail.d/sshd.local /etc/fail2ban/jail.d/sshd.local.disabled.<ROLLBACK_SUFFIX>
기존 jail 백업 복원
sudo cp --preserve=all /etc/fail2ban/jail.d/sshd.local.<BACKUP_SUFFIX>.bak /etc/fail2ban/jail.d/sshd.local
작업 전 실제 백업이 있었던 경우에만 실행합니다.
검사 후 설정 reload
sudo fail2ban-client -t && sudo fail2ban-client reload
복원 후 공개키 세션
ssh -o PreferredAuthentications=publickey -o PasswordAuthentication=no -o KbdInteractiveAuthentication=no -t <ADMIN_USER>@<SERVER_IP> 'id && sudo -v'
  • 전체 ban을 해제하지 않고 정확한 관리자 IP만 unban했다.
  • 현재 SSH·콘솔 세션을 유지했다.
  • 이전 파일 복원 또는 신규 파일 비활성화 중 맞는 분기만 사용했다.
  • 설정 검사 후 reload하고 새 공개키 세션을 확인했다.
결과 읽기

unban 뒤에도 접속이 안 되면 상위 방화벽·호스트 기본 규칙·sshd 자체 정책을 분리해 확인합니다.

다음 판단

오탐 로그를 보존하고 필터·임계값·관리망 주소 변경을 검토합니다.

SECURITY CHECK

운영 전 마지막 보안 점검

  • UFW·firewalld·직접 nftables 중 규칙 소유자를 하나로 유지한다.
  • 관리자 CIDR을 ignoreip에 넣고 콘솔·기존 세션을 확보한다.
  • 배포판 jail.conf는 수정하지 않고 .local만 사용한다.
  • 상위 SSH CIDR 제한과 공개키 인증을 계속 유지한다.
  • 오탐 시 정확한 IP만 unban하는 복구 절차를 시험한다.

COMMON ERRORS

자주 막히는 지점

관리자 자신이 차단됨

증상
새 SSH 연결이 timeout 또는 즉시 거부됩니다.
가능한 원인
NAT 뒤 실제 출발지와 ignoreip CIDR이 다르거나 이미 ban됐을 수 있습니다.
확인 순서
콘솔·기존 세션에서 SSH_CONNECTION과 ban 목록을 대조하고 정확한 IP만 unban합니다.
트러블슈팅으로 이어보기

sshd jail이 시작되지 않음

증상
No file(s) found 또는 journal backend 오류가 기록됩니다.
가능한 원인
파일 logpath와 systemd backend를 섞었거나 python-systemd 지원이 없을 수 있습니다.
확인 순서
systemd backend에서는 logpath를 제거하고 journal의 실제 OpenSSH unit을 확인합니다.
트러블슈팅으로 이어보기

ban 카운터는 증가하지만 접속이 계속됨

증상
Fail2ban에는 banned IP가 있으나 방화벽에서 차단되지 않습니다.
가능한 원인
배포판 action과 실제 UFW·firewalld·nftables 소유자가 불일치할 수 있습니다.
확인 순서
유효 action과 활성 방화벽을 확인하고 두 방화벽을 동시에 켜지 않은 채 배포판 기본 action을 복원합니다.
트러블슈팅으로 이어보기

PRIMARY REFERENCES

공식 문서

설치 저장소와 지원 버전은 바뀔 수 있습니다. 검토일 이후에는 링크된 공식 문서와 현재 서버의 패키지 후보 버전을 함께 확인하세요.

도구 빠른 검색

최근 사용한 도구를 다시 열거나, 이름과 기능으로 검색하세요.

검색어와 도구의 입력·결과는 저장하지 않습니다.

↑↓ 이동 · Enter 열기 · Esc 닫기