Django 개발 일기 - 2
Django에 fail2ban 적용하기
by HOON
Last updated on Feb. 14, 2024, 2:46 p.m.
현재 보고있는 Web Application의 구조는
AWS(Lightsail), Docker, Django로 구성되어있습니다.
이전 포스트에서 남겼던 보안이슈 덕분에 공부하고 설치 적용까지 한 fail2ban에 대하여 게시글을 쓰고자 합니다.
개요
먼저 fail2ban이란,
이름에서 유추 할 수 있듯이 접속 실패 -> ban 해주는 보안 프로그램입니다.
처음 도메인을 구매하고, 서버를 오픈 할 당시 아무도 알리지 않은 주소에 이렇게나 열정적으로 사람들이 접속 할 줄 몰랐습니다 ^^..
이렇게 여러 IP에서 이상한 접근시도를 하는걸 확인할 수 있습니다.
fail2ban 설치 및 적용
sudo apt-install fail2ban
명령어로 fail2ban을 설치해줍니다.
fail2ban의 작동방식은, access.log를 읽어 미리 정의한 Regex에 필터된 데이터의 IP를 찾아 일정 횟수 이상 시도가 있을경우 관리자가 설정한 기간동안 Ban시키는 프로그램입니다.
따라서 설치 이후 fail2ban이 나의 서버 로그를 읽을 수 있도록 해줘야합니다.
1. fail2ban 설정하기
첫번째로 fail2ban에서 환경설정을 해줍니다.
cd /etc/fail2ban/
으로 이동 후, ls명령어를 통해 파일,디렉토리 리스트를 보면
jail.conf, jail.local, filter.d 를 유심히 살펴보겠습니다.우선 jail.conf와 jail.local의 차이를 보자면
.conf파일은 fail2ban 서비스가 내려갈경우 설정해둔 조건값이 초기화될 수 있습니다. 반대로 local파일은 개인이 저장해둔 설정파일을 서비스가 재시작 되더라도 유지 할 수 있습니다.
따라서 conf파일을 local파일로 복사한 후 local파일에서 조건값을 설정해두면 됩니다. (local파일이 없을경우입니다 파일이 이미 존재한다면 에디터로 바로 수정해서 사용해도 됩니다.)
예로 local 파일 중 sshd 접근에 대해서 Default 값이 어떤식으로 적용되어있는지 보겠습니다.
예로 sshd의 경우 이런식으로 설정들이 저장되어있고, 같은 형태로 여러개의 서비스가 이미 정의되어있는 상태입니다.
필요한 서비스가 있으면 해당 서비스를 활성화시키면 되고, 없다면 만드시면 됩니다.저는 제 서버에 맞게 필요한 서비스가 필요하여 개인적으로 추가 한 nginx-banroute를 한번 보겠습니다.
해당이미지에서 각 문구는 의미는 아래와 같습니다.
enabled = true #해당 기능 활성화
chain = DOCKER-USER
port = http, https #port는 http, https 검사
filter = nginx-banroute #fiter.d에서 작성한 nginx-banroute.conf 파일을 참고하겠다.
logpath = ~/logs/*.log #로그는 해당 위치에서 참고하겠다.
maxretry = 2 #몇번의 재시도까지 허용할지
findtime = 600 #각 재시도 별 interval
bantime = -1 # -1은 영구 ban
다음으로 filter.d 디렉토리를 살펴보겠습니다.
여기서는 실제 로그를 분석 할 때 regex 표현식을 정의해두고 filter에 걸리도록 설정하는 .conf파일들이 모여있습니다.
제 경우에는 nginx-banroute.conf 라는 파일을 생성하여 정규식을 설정해두었습니다.
failregex는 해당 정규식에 포함되는 ip를 포함하여 밴 하기 위한 조건문을 저장하는 변수이며
ignoreregex는 해당 정규식에 포함되는 ip는 무시하겠다 라는 뜻입니다.
이렇게 하면 fail2ban의 설정은 끝입니다.
2. nginx의 로그 마운트하기
초반에 언급한것처럼 fail2ban은 log 데이터를 읽어 해당 ip를 ban할지 결정합니다.
저는 Docker에서 가동되고있기떄문에, Docker의 nginx 로그를 Local로 마운트하겠습니다.
이렇게 nginx의 volumnes에 한 줄 추가해줍니다.
- /mount될 로컬경로:/nginx경로
명령어 입력하고나면, 도커내에서 가동되는 nginx의 로그(access.log, error.log)는 이제 정의한 local경로에서 참고 할 수 있습니다. 그 이후 미리 설정한 fail2ban의 설정파일(jail.conf 혹은 jail.local)에서 입력해주면
앞으로 fail2ban은 해당 로그 파일을 참조하여 ip를 ban 할 수 있습니다.
3. local의 iptable 변경하기
앞에서 언급한것처럼 제 서버의 환경은 Django가 Docker에서 가동 되고 있습니다.
Docker에서 fail2ban을 적용하려면 local의 iptables를 수정해야합니다. (Docker는 자체 Iptable을 갖고있어, local보다 먼저 인식되어 fail2ban의 적용이 안됩니다.)실제 fail2ban 테스트 시
sudo fail2ban-client status
를 통해 보면, ban은 되었다고 나오지만 실제 해당 Ip로 서버에 접속해보면 접속이 잘 되는문제가 있었습니다.따라서 이는 Docker의 iptable보다, Local 환경의 iptable이 먼저 인식되도록 변경함으로써 적용시킬 수 있었습니다.
(참고 https://serverfault.com/questions/1043964/fail2ban-iptables-entries-to-reject-https-not-stopping-requests-to-docker-contai)
Local에서 iptables -L
명령어를 입력하면 아래와 같이 리스트가 보입니다.
현재 제 상태는 iptables의 FORWARD에 fail2ban에서 정의한 내용을 맨 위로 인식하도록 명령어를 설정하여 top에 위치해있습니다.
sudo iptables -I FORWARD 1 -p tcp -j f2b-서비스이름
이렇게 local의 iptable을 수정해야 Docker보다 local에서 먼저 인식 할 수 있습니다.
결과
이렇게 fail2ban을 설정 한 후 10일정도 지난 뒤 실제 ban 당한 ip들을 살펴보니
이렇게 68개의 ip가 영구ban을 당했으며, sshd의 경우엔 677개의 ip가 ban이 되었습니다.
이 포스트를 보는분들은 부디 미리 준비해서 해킹당하는일이 없도록 하길 바라겠습니다!!
TIP 참고할만한 명령어들
sudo fail2ban-client status #ban 된 ip 확인
sudo fail2ban-client status sshd #특정하여 ban 된 ip 확인
sudo service restart fail2ban # 서비스 restart
- 실제 postgresql 도 확인하기(추가예정)
Leave a Comment:
sora
GOOD
Updated: Jan. 29, 2024, 2:18 p.m.