리눅스 기초 시리즈의 54번째 시간입니다! 지난 시간 우리는 AWS S3와 rclone을 활용해 데이터의 최후 보루인 오프사이트 백업을 구축했습니다. 이제 데이터는 안전합니다. 하지만 백업을 믿고 대문을 열어둘 수는 없겠죠? 서버를 운영하다 보면 누군가 끊임없이 내 SSH 비밀번호를 맞추려고 시도하는 것을 발견하게 됩니다.
이런 무차별 대입 공격(Brute Force)은 마치 밤새도록 우리 집 도어락 번호를 하나씩 눌러보는 불청객과 같습니다. 오늘은 이런 끈질긴 공격자들을 실시간으로 감시하고, 몇 번의 실패 즉시 지옥 끝까지(?) 차단해버리는 보안 보안관, Fail2ban 설정법을 저의 경험담과 함께 정리해 보겠습니다.
1. 나의 경험담: "로그 파일에서 발견한 수천 마리의 모기떼"
제 기술 블로그인 sunyjini.com 서버를 운영하던 초기, 호기심에 인증 로그 파일(/var/log/auth.log)을 열어본 적이 있습니다. 눈을 의심했습니다. 제가 잠든 사이, 전 세계 각지의 IP들이 제 SSH 포트로 수천 번의 로그인 시도를 하고 있었거든요. 그들은 마치 피 냄새를 맡고 몰려드는 모기떼 같았습니다.
비밀번호를 복잡하게 설정해두어 뚫리지는 않았지만, 계속되는 시도 때문에 서버 자원이 낭비되고 로그 파일 용량이 커지는 게 무척 신경 쓰였습니다. 그때 도입한 것이 바로 Fail2ban이었습니다. 설치하자마자 무지성으로 번호를 눌러대던 IP들이 하나둘씩 'Banned' 목록에 박히는 것을 보며, 비로소 제 서버에 든든한 경비원을 고용했다는 안도감을 느꼈습니다.
2. Before: "멍하니 당하고만 있는 무방비 서버"
Fail2ban을 쓰기 전에는 공격자가 1만 번을 시도하든 10만 번을 시도하든 서버는 그저 "틀렸습니다"라고 친절하게 대답만 해줍니다. 공격자에게 무한한 기회를 주는 셈이죠. 이는 보안의 가장 기초적인 구멍 중 하나입니다.
공격 상황 확인 코드:
# 로그인 실패 기록만 골라보기 (얼마나 많은지 확인해보세요)
grep "Failed password" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -nr | head -n 10
(▲ Before: 위 명령어를 쳤을 때 특정 IP 앞에 숫자가 100단위로 붙어 있다면, 누군가 지금 여러분의 서버 문손잡이를 계속 돌려보고 있다는 증거입니다.)
3. Action: 지옥의 경비원 Fail2ban 배치하기
이제 Fail2ban을 설치하고, 5번만 틀려도 해당 IP를 10분간(혹은 영구히) 차단하도록 설정해 보겠습니다. 원본 설정 대신 .local 파일을 만들어 덮어씌우는 것이 정석입니다.
철통 보안 설정 코드:
# 1. Fail2ban 설치
sudo apt update && sudo apt install fail2ban -y
2. 로컬 설정 파일 생성
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
3. [sshd] 섹션 수정 (5번 실패 시 10분 차단)
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
bantime = 600
4. 서비스 재시작
sudo systemctl restart fail2ban
(▲ Action: 설정을 마친 뒤, Fail2ban은 백그라운드에서 로그 파일을 눈이 빠지게 감시합니다. 조건이 충족되는 순간 리눅스 방화벽(IPTables나 NFTables)에 해당 IP를 즉각 등록해버립니다.)
4. After: 평화를 되찾은 클린 서버
Fail2ban을 도입한 뒤 제 서버 로그는 놀라울 정도로 깨끗해졌습니다. 공격자 입장에서는 몇 번 시도하자마자 서버가 응답을 멈춰버리니(차단), 더 이상 공격할 맛이 나지 않겠죠.
달라진 점들:
- 로그 노이즈 제거: 불필요한 로그인 실패 로그가 사라져 진짜 중요한 로그를 확인하기가 편해졌습니다.
- 자원 보호: SSH 데몬에 가해지는 무차별적인 접속 부하가 사라져 시스템 응답 속도가 개선되었습니다.
- 2차 보안망 확보: SSH 키 인증(41편)과 병행하여 쓰니, 이제는 외부 침입 걱정을 거의 하지 않게 되었습니다.
5. 실험 요약 및 팁
| 명령어 / 옵션 | 역할 | 비유 |
| fail2ban-client status | 차단 현황 및 통계 확인 | 블랙리스트 명단 보기 |
| maxretry | 차단 전 허용할 실패 횟수 | 도어락 기회 횟수 |
| bantime | 접속을 차단할 시간(초) | 반성문 쓰는 시간 |
| findtime | 실패 횟수를 누적할 시간 범위 | 기억력의 유효 기간 |
6. 마치며: 당신의 서버에 눈을 달아주세요.
리눅스 기초 54단계를 거치며 우리는 이제 시스템의 자율 방어 체계까지 완성했습니다. 인프라는 만드는 것보다 '지키는 것'이 더 어렵다고들 합니다. 하지만 Fail2ban 같은 똑똑한 도구를 내 손으로 튜닝할 수 있다면, 더 이상 어둠 속의 공격자들이 두렵지 않을 것입니다.
오늘의 인사이트: "최고의 보안은 공격자를 화나게 하는 것이 아니라, 공격할 가치가 없다고 느끼게 만드는 지루함을 선물하는 것이다."
54번째 이야기를 마칩니다. 이제 우리만의 '무적 요새'가 거의 다 지어졌습니다. 다음 시간에는 리눅스 서버 운영의 화룡점정, '웹 서버 응답 속도를 광속으로 끌어올리는 캐시 엔진(Redis) 연동 및 튜닝'에 대해 다뤄보겠습니다.
이 글이 여러분의 서버를 더욱 평화롭게 만들었나요? 혹시 설정 실수로 내 자신의 IP가 차단되어 당황하고 계신가요?
차단된 본인의 IP를 즉시 해제하는 긴급 명령어와 '내 IP는 절대 차단하지 마라(ignoreip)' 설정을 다음 포스팅 부록으로 준비해 드릴까요?
'IT' 카테고리의 다른 글
| [리눅스 기초 #56] 명령어로 창조하는 클라우드 세상: 테라폼(Terraform)으로 코드형 인프라(IaC) 시작하기 (0) | 2026.02.22 |
|---|---|
| [리눅스 기초 #55] 데이터베이스의 비명을 멈추는 방패: Redis 캐싱으로 웹 서버 광속 만들기 (0) | 2026.02.21 |
| [리눅스 기초 #53] 내 서버 데이터의 최후의 보루: S3와 rclone으로 오프사이트 백업 완성하기 (0) | 2026.02.20 |
| [리눅스 기초 #52] "git push"면 배포 끝: GitHub Actions로 나만의 CI/CD 구축하기 (0) | 2026.02.20 |
| [리눅스 기초 #51] 서버 설정도 '커밋' 하세요: Git으로 관리하는 리눅스 환경과 GitOps 입문 (0) | 2026.02.18 |