UFW + fail2ban으로 Ubuntu 서버 보안 강화

UFW(Uncomplicated Firewall)는 iptables/nftables를 쉽게 다루기 위한 우분투 기본 방화벽 프론트엔드이고, fail2ban은 로그를 감시하다가 비정상적인 접속 시도가 반복되면 해당 IP를 자동으로 차단하는 침입 차단 도구다. UFW가 “어떤 포트를 열지”를 정한다면, fail2ban은 “열어둔 포트를 무차별 대입 공격으로 두드리는 IP를 얼마나 빨리 잘라낼지”를 담당한다. 이 글에서는 두 도구를 함께 설치하고 SSH를 기준으로 실전 설정을 정리한다.

UFW 설치 및 기본 방화벽 규칙 설정

우분투에는 대부분 UFW가 기본 설치되어 있지만, 없다면 아래 명령으로 설치한다.

sudo apt update
sudo apt install ufw

기본 정책은 들어오는 연결은 모두 거부하고 나가는 연결은 허용하는 형태로 잡는다.

sudo ufw default deny incoming
sudo ufw default allow outgoing

필요한 서비스 포트만 허용한다. SSH는 브루트포스 공격 표적이 되기 쉬우므로 limit으로 등록해 일정 시간 내 반복 접속 시도를 자동으로 제한한다.

sudo ufw limit 22/tcp        # SSH (rate limiting 적용)
sudo ufw allow 80/tcp        # HTTP
sudo ufw allow 443/tcp       # HTTPS

SSH 포트를 기본값(22)에서 바꿔 쓰는 경우 해당 포트 번호로 규칙을 등록해야 한다. 규칙을 다 정했으면 방화벽을 활성화한다.

sudo ufw enable
sudo ufw status verbose

status verbose 출력에서 각 포트의 정책과 로깅 여부를 확인할 수 있다. fail2ban이 UFW 로그를 참조하려면 로깅이 켜져 있어야 하므로, 꺼져 있다면 아래 명령으로 활성화한다.

sudo ufw logging on

fail2ban 설치 및 SSH 보호 설정

fail2ban을 설치한다.

sudo apt install fail2ban

설정 파일인 /etc/fail2ban/jail.conf는 패키지 업데이트 시 덮어써질 수 있으므로 직접 수정하지 않는다. 대신 jail.local을 만들어 여기에 필요한 부분만 오버라이드한다.

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

[sshd] 섹션을 찾아 아래와 같이 설정한다.

[sshd]
enabled = true
port    = ssh
filter  = sshd
logpath = /var/log/auth.log
maxretry = 5
findtime = 600
bantime  = 3600

각 옵션의 의미는 다음과 같다.

  • maxretry: findtime 안에 허용하는 최대 실패 횟수. 이 횟수를 넘기면 차단한다.
  • findtime: 실패 횟수를 세는 관찰 시간(초). 600이면 10분 안에 maxretry번 실패해야 차단 대상이 된다.
  • bantime: 실제 차단 지속 시간(초). 3600이면 1시간 동안 차단한다. -1로 설정하면 영구 차단이다.

설정을 저장한 뒤 서비스를 재시작하고 상태를 확인한다.

sudo systemctl restart fail2ban
sudo fail2ban-client status sshd

현재 차단된 IP 목록과 실패 횟수 통계가 출력된다.

$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed: 2
|  |- Total failed:     47
|  `- Journal matches:  _SYSTEMD_UNIT=ssh.service + _COMM=sshd
`- Actions
   |- Currently banned: 1
   |- Total banned:     6
   `- Banned IP list:   203.0.113.10

웹 서버(Apache/Nginx) jail 추가하기

SSH뿐 아니라 Apache나 Nginx가 실행 중이라면, 인증 실패 로그를 대상으로 하는 jail도 함께 켜두는 것이 좋다. Apache 기준으로는 다음 jail을 활성화한다.

[apache-auth]
enabled = true
port    = http,https
logpath = /var/log/apache2/error.log

[apache-badbots]
enabled = true
port    = http,https
logpath = /var/log/apache2/access.log

WordPress 로그인 페이지(wp-login.php)를 대상으로 한 무차별 대입 공격이 잦다면, WordPress 로그인 실패를 감지하는 필터를 별도로 만들어 jail로 등록하는 방법도 있다. 이 경우 WordPress 쪽 로그 포맷에 맞는 정규식 필터를 /etc/fail2ban/filter.d/에 직접 작성해야 한다.

주의사항 및 팁

  • 자기 자신을 밴하지 않기: SSH 접속을 반복 실패하면 관리자 본인도 차단당할 수 있다. 고정 IP에서 접속한다면 jail.localignoreip 항목에 자신의 IP를 미리 등록해두면 안전하다. 반대로 재택/이동 중이거나 WSL2처럼 접속 IP가 자주 바뀌는 환경이라면 ignoreip에 의존하지 말고, 밴 당했을 때 다른 경로(서버 콘솔, 클라우드 제공사 콘솔 등)로 접속해 해제하는 절차를 미리 알아둬야 한다.
  • 차단 해제 명령: 실수로 자신이 차단됐다면 다음 명령으로 즉시 해제할 수 있다.
    sudo fail2ban-client set sshd unbanip 203.0.113.10
  • bantime -1은 신중하게: 영구 차단은 공유 IP(사내 NAT, 클라우드 서비스 아웃바운드 IP 등)를 잘못 차단하면 다른 정상 사용자까지 막을 수 있다. 처음에는 짧은 bantime으로 시작해 로그를 보며 조정하는 편이 안전하다.
  • UFW와 fail2ban 규칙 충돌 확인: sudo iptables -L -n 또는 sudo ufw status numbered로 fail2ban이 추가한 차단 규칙이 실제로 적용됐는지 주기적으로 확인한다.

마치며

UFW는 어떤 포트를 열어둘지 결정하는 1차 방어선이고, fail2ban은 그 열린 포트를 두드리는 반복 공격을 자동으로 걸러내는 2차 방어선이다. SSH jail만 켜두어도 무차별 대입 공격의 상당수를 막을 수 있고, 웹 서버를 운영한다면 apache-auth/nginx-http-auth 같은 jail도 함께 켜두는 것이 좋다. 다만 자동 차단은 관리자 자신도 예외 없이 차단할 수 있으므로, ignoreip 설정과 fail2ban-client unbanip 해제 절차는 도입 시점에 반드시 함께 익혀둬야 한다.

답글 남기기