내 사이트 공격해서 차단당하기 (fail2ban)

Muji1412·2025년 5월 15일
post-thumbnail

"ㅎ 사용자님"
"예?"
"리눅스 서버 그따구로 관리하시면 다 털리시는데ㅎ"
"예? ssh로만 연결하는데 안전한거 아니에요?"
"ㅎㅎ 아닌뎅"

fail2ban을 적용시켜 보자

"그.. 게 뭐고 왜 쓰는데요"

ssh 일정횟수 로그인 실패시 ip차단
브루트포스 공격 방어
방화벽 세팅, PermitRootLogin no 등이 1차 방어막이면 이건 2차 방어막

Fail2ban이 작동하는 구조는 대략 이러하다

  1. 로그를 까본다
  2. 로그에 수상쩍은 놈이 있는지 체크한다
  3. 내가 생성해놓은 정책에 위반하는 녀석 밴!

나는 nginx를 사용하고 있고, nginx가 만들어주는 로그를 기반으로 밴을 만들어주려고 한다.

설치

sudo apt update
sudo apt install fail2ban

시작 후 활성화

sudo systemctl start fail2ban
sudo systemctl enable fail2ban

설정파일 세팅(필수)

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
-> 꼭 해줘야함. 안해주면 그냥 아무것도 세팅 안돼있음.
이렇게 해줘야 세팅이 작동하고, 로컬 세팅파일을 만들어서 돌려줘야함 (업데이트시 파일 날라감)
enabled = true로 되어 있는지 확인하고,
bantime (차단 시간)
maxretry (최대 시도 횟수) 
findtime (감시 시간)
등을 조정해준다.

물론 원래 파일이 제공해주는 설정을 써도 되지만, 나는 sshd 관련 세팅이랑
nginx 세팅만 구현해보고 싶었기에, sshd + nginx 세팅만 추가해줬다.
각자 입맛에 맞게 세팅해놓도록 하자!

[sshd]
enabled = true
port    = ssh (이 부분은 자신에 포트에 따라서 알아서 변경하도록 하자)
maxretry = 5
bantime = 24h

이 방식으로 ssh 브루트포싱을 차단할 수 있다.

실행이 안돼요

[DEFAULT]
enabled = true

디폴트 값 안에 세팅을 true로 해놓으면 모든 jail 세팅들이 전부 켜지게 된다.
일단 false로 변경해주고, 파일을 하나씩 true로 변경해보며 어느쪽이 문제인지 찾아보자.

파일을 못 읽어요

분명 존재하는 파일, 올바른 파일주소, 파일내용도 정상이었음에도 불가하고 실행이 안됐고,
문제를 해결하기 위해서 fail2ban 재설치, 기본 파일로 실행 등 여러가지 시도해봤다.
root 사용자로 실행돼야하지만 어떤 이유여서인지 파일들을 읽지 못했고,
명확한 이유는 모르겠지만 기본 jail 세팅들을 모두 삭제하고, default의 enabled값을 false로 바꾼 후 하나하나 jail을 다시 켜보면서 어떤 파일이 문제인지 확인했다.

나같은 경우에는 filter 중에 badbots 파일이 없었고, 그에 따라 오류가 발생했었다.

ls -l /etc/fail2ban/filter.d/nginx*

해당 명령어를 통해 filter에 적절한 파일이 있는지 없는지 확인할 수 있다.
nginx이 아닌 다른 필터파일을 사용할 경우에는 nginx를 적절하게 바꿔줘서 사용하도록 하자.

limit-req

내가 제일 구현해보고 싶었던 기능이다.
유저가 너무 많은 요청을 보내면 밴을 해버리는 기능.

내 jail.local 파일에 이렇게 구현해 두었다.

[nginx-limit-req]
enabled = true
filter  = nginx-limit-req
port    = http,https
logpath = /var/log/nginx/error.log
maxretry = 10
bantime = 6000

하지만 위에 쓴 대로, nginx의 에러파일 기반으로 움직이니, nginx 세팅파일도 바꿔주도록 하자.

http {
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=5r/s;
    
    server {
        location / {
            limit_req zone=mylimit burst=10 nodelay;
        }
    }
}

이렇게 넣어주도록 하자.
대충 해석하면
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=5r/s;
'초당 5번 리퀘스트까지 괜찮고, 접속자 아이디 기록해둘 공간 10메가바이트, 이름은 mylimit'
limit_req zone=mylimit burst=10 nodelay;
'아, 거기에 추가로 10번까지 와도 괜찮아. 일시적으로 초당 15건까지는 괜찮아!'
'근데 그건 일시적이고 그거 넘으면 경고 1회 부여해줘'

logpath = /var/log/nginx/error.log
maxretry = 10
bantime = 6000

'nginx 에러로그로 감시하고, 위에 말한 경고가 10번 쌓이면 해당 아이피 100분(6000) 밴해줘.
라는 뜻이 되게 된다.

공격해보기

거창하게 '공격해보기' 라고 적었지만, 따로 공격툴을 가진것도 아니므로 f5를 연타해보자.


계속 연타하다보면 초당 5회를 초과하여, 503 에러창을 띄워주게 된다.

이렇게 계속 요청하다보면!

짜잔! 내 아이피가 차단당했다. 하지만 여전히 다른 ip로는 접속할수 있다!

sudo fail2ban-client status nginx-limit-req


Currently banned값이 1, 나라는 말이다.
아래에는 Banned IP list가 나와서, 누가 밴을 당했는지도 알 수 있다.

profile
박치기공룡의 개발일지

0개의 댓글