#0.9.2 - 보안 기능 강화
블로그 사이트를 공개한 이후 여러 악성 요청들이 하루도 빠짐없이 들어오고 있습니다. 현재 블로그가 올라가 있는 서버는 자택에 구비된 미니 PC를 서버 컴퓨터로 사용 중이긴 한데, 딱히 털어갈 것도 없어서 어떤 조치를 하지 않았습니다만...
한번은 로그 모니터링에서 경고 요청 건수가 1,000건이 넘어가는 것을 보고 당황하여 찾아보니, 나쁜 녀석들이 짧은 시간 동안 무단 경로 요청을 지속적으로 보내는 것을 확인하였습니다.
개빡친다..
초기 대응: Cloudflare 설정 검토
처음에는 블로그의 호스팅 환경을 관리하는 Cloudflare의 무료 플랜이 DDoS 공격을 자동으로 방어해줄 것으로 어렴풋이 알고 있었기에 무슨 상황인지 이해하지 못했습니다. 대충 찾아보니, Cloudflare의 무료 플랜은 3초 이내의 짧은 공격이나 정교한 공격에 대한 방어에는 한계가 있다고 하네요.. 프로 플랜으로 업그레이드하면 더 세밀한 제어가 가능하지만, 도메인당 구독 방식이라 비용 부담이 커서 다른 해결책을 모색하기로 했습니다.
웹애플리케이션에서 방어로직 추가
Cloudflare의 추가 기능에 의존하는 대신, 돈을 아끼기 위해 제어권을 확보하기 위해 애플리케이션 미들웨어(middleware) 단에서 악성 요청을 직접 처리하는 방식을 택했습니다. iptables나 NGINX 같은 서버 레벨에서의 제어는 저에게는 반갑지 않은 영역이었기 때문입니다.
claude code에게 보편적인 악성 경로 패턴을 추가해달라고 부탁하여 일단 간단한 알고리즘으로 방어로직을 구현하였습니다.
async use(req: Request, res: Response, next: NextFunction) {
const clientIp = getRealClientIp(req);
const userAgent = req.get('User-Agent') || '';
const requestPath = req.path;
try {
// 1. IP 차단 목록 확인
if (await this.isIPBlocked(clientIp)) {
return this.blockRequest(res, 'IP_BLOCKED', clientIp, requestPath, userAgent);
}
// 2. 악성 경로 패턴 확인
if (this.isMaliciousPath(requestPath)) {
await this.autoBlockIP(clientIp, `Malicious path access: ${requestPath}`, requestPath, userAgent);
return this.blockRequest(res, 'MALICIOUS_PATH', clientIp, requestPath, userAgent);
}
// 3. 악성 User-Agent 확인
if (this.isMaliciousUserAgent(userAgent)) {
await this.autoBlockIP(clientIp, `Malicious User-Agent: ${userAgent}`, requestPath, userAgent);
return this.blockRequest(res, 'MALICIOUS_USER_AGENT', clientIp, requestPath, userAgent);
}
// 4. 허용된 요청
next();
} catch (error) {
this.logger.error('WAF Middleware error', { error: error.message, stack: error.stack, ipAddress: clientIp });
next(); // 에러 시 통과시킴 (가용성 우선)
}
}
요청이 들어오면 가장 먼저 기존에 차단된 기록이 있는 IP인지 확인합니다. 이 단계에서 블랙리스트에 등록된 IP임이 확인되면, 요청에 대한 응답을 더 이상 진행하지 않고 즉시 403 Forbidden 응답을 반환합니다. 새로운 IP라도 악성 요청이 감지되면, 해당 IP는 즉시 403 Forbidden 응답을 받습니다. 이와 동시에 해당 IP는 임시 차단 목록에 등록되어, 이후 같은 주소에서 발생하는 모든 요청을 자동으로 거부합니다.
관리페이지 보안 섹션 추가
추가한 보안 기능이 예상대로 작동하는 것을 확인했습니다. 기능을 배포한 지 불과 1시간 만에 크롤러 봇, 알 수 없는 에이전트(unknown agent), 악성 경로 요청 등 다양한 비정상적인 접근들이 성공적으로 차단된 것을 로그를 통해 확인했습니다.
조금 감격스러운 기분입니다요..
개선 및 추가 사항
현재는 단순 IP 차단에 머물러 있지만, 향후에는 요청 패턴 분석과 같은 더 정교한 로직을 추가하여 방어 능력을 고도화할 예정입니다. (with claude code 🤩)