.git 폴더를 막고 4일, 스캐너 IP는 178개에서 175개로 그대로였지만 요청은 27,997건에서 589건으로 줄었다

.git 폴더를 막고 4일, 스캐너 IP는 178개에서 175개로 그대로였지만 요청은 27,997건에서 589건으로 줄었다

지난 글에서 서버 요청의 16.7%가 .git 폴더를 뒤지는 요청이었고, 그중 4,917건은 실제로 파일을 내주고 있었다는 것을 확인하고 아파치 설정으로 막았습니다. 그 뒤 4일 동안 같은 로그를 다시 셌습니다. 차단 전 4일과 차단 후 4일을 같은 길이로 놓고 비교하면, .git을 건드린 IP 수는 178개에서 175개로 거의 같은데 요청 수는 27,997건에서 589건으로 97.9% 줄었습니다. 스캐너의 수는 그대로이고, 스캐너 하나가 보내는 요청 수가 157건에서 3.4건으로 줄어든 것입니다. 첫 요청에서 403을 받으면 그 뒤를 이어가지 않는다는 뜻입니다.

차단 전 4일과 후 4일

설정을 적용한 시각(9월 12일 15:25, 서버 시간)을 기준으로 앞뒤 96시간씩 잘랐습니다. 접속 로그는 combined 형식 줄만 세었습니다.

항목 차단 전 4일 차단 후 4일 변화
전체 요청 336,357 689,077 다른 사이트 봇 유입으로 증가
.git 요청 27,997 (8.3%) 589 (0.09%) −97.9%
.git 요청 중 200 415 0 유출 0
.git 전송량 14.0MB 115KB −99.2%
.git을 요청한 IP 178 175 거의 같음
IP당 .git 요청 157.3 3.4 −97.9%
전체 404 61,339 38,821 −36.7%
전체 403 728 4,798 6.6배
404 응답 1,065,189건을 경로 모양으로 나눈 막대그래프. .git 폴더 492,189건, .php 파일 261,248건, .env 파일 67,579건, 그 밖 244,173건
404의 46%가 /.git/ 아래 경로였고, 없는 PHP 파일이 그다음입니다.

전체 요청이 두 배가 된 것은 9월 16일 하루에 74.7.227.x 대역 IP 네 개가 같은 서버의 다른 사이트 게시판을 약 23만 건 긁어 간 탓이고, .git과는 관계가 없습니다. 그래서 비율보다 건수로 봐야 합니다.

스캐너 수는 그대로, 요청만 줄었다

차단 전에 .git을 요청한 IP 178개 가운데 1,000건 넘게 보낸 IP가 4개 있었고, 이 넷이 27,261건(97.4%)을 차지했습니다. 차단 후에는 1,000건 넘는 IP가 없고 가장 많이 보낸 IP도 51건입니다.

IP당 .git 요청 차단 전 IP 수 차단 후 IP 수
1건 55 69
2~5건 85 76
6~20건 31 27
21~100건 2 3
101~1,000건 1 0
1,000건 초과 4 0

1~20건을 보내는 IP는 전후가 비슷합니다. 이들은 /.git/config, /.git/HEAD 같은 파일 몇 개만 찔러 보고 지나가는 탐색 단계의 스캐너라, 200이 나오든 403이 나오든 요청 수가 같습니다. 사라진 것은 1,000건 이상을 보내던 넷입니다. 차단 전 .git 요청 27,997건의 80.2%는 .git/objects/ 아래 객체 파일이었는데, 이는 configHEAD가 200으로 열린 뒤에야 시작되는 두 번째 단계입니다. 첫 단계가 403으로 막히니 두 번째 단계가 없어졌습니다. 차단 후 .git/objects/ 요청은 0건입니다.

같은 IP가 전후에 어떻게 달라졌나

양쪽 기간에 모두 나타난 IP는 16개입니다. 그중 차단 전 10,231건을 보낸 45.148.10.120은 차단 후 5건을 보내고 그쳤습니다. 다른 15개는 전후 모두 20건 이하였고, 그 안에서는 늘기도 줄기도 했습니다. 스캐너가 목록에서 이 서버를 지운 것이 아니라, 매번 다시 와서 첫 파일을 요청하고 403을 받고 돌아간다고 봐야 합니다. 차단 후 .git 요청의 UA는 차단 전 85.2%를 차지했던 Firefox/78 문자열이 사라지고, 윈도 브라우저 UA 문자열이 절반 가까이입니다. 객체 파일을 긁던 도구가 쓰던 UA와 탐색용 도구가 쓰는 UA가 달랐던 셈입니다.

.git 첫 요청 다음에 온 요청 차단 전 (IP 수) 차단 후 (IP 수)
또 다른 .git 경로 63 40
없음 (그 요청이 마지막) 31 30
/.env 계열 30 59
/ (홈) 20 17
/graphql 18 상위 8개 밖

차단 후에는 .git에서 403을 받은 IP가 다음으로 .env를 찔러 보는 경우가 늘었습니다. 스캐너가 .git.env를 한 묶음으로 돌리는 것이고, 하나가 막혀도 다른 하나는 계속 시도합니다.

.env는 22%만 막혔다

같은 설정에 .env도 넣었는데, 로그를 보면 .env 요청은 차단 전 13,013건에서 차단 후 16,986건으로 오히려 늘었고, 403은 3,799건(22.4%)뿐입니다. 12,555건(73.9%)은 여전히 404입니다. 이유는 경로에 있습니다.

요청 경로 응답 크기 시간 이유
/.env, /.env.bak 403 199B 16ms FilesMatch가 잡음
/laravel/.env, /api/.env 404 55,096B 68ms 폴더가 없어 워드프레스 404 페이지
다른 사이트의 /backend/.env 404 196B 폴더가 없어 아파치 404

루트 바로 아래 .env는 파일 이름 규칙에 걸려 403이 됩니다. 그런데 스캐너는 /laravel/.env, /backend/.env, /admin/.env처럼 하위 폴더 수십 개를 돌립니다. 그 폴더가 없으면 아파치는 파일 이름 규칙을 볼 것도 없이 404를 내고, 워드프레스 사이트에서는 .htaccess가 없는 경로를 index.php로 넘겨 55KB짜리 404 페이지를 만듭니다. 차단 후 4일 동안 이렇게 워드프레스가 렌더링한 .env 404가 1,697건이었습니다. 차단 전 2,116건과 큰 차이가 없습니다. .env.git과 달리 첫 파일이 막혀도 다음 경로를 계속 시도하니, 파일 이름이 아니라 URL 패턴으로 막아야 효과가 있습니다. 이 부분은 다음에 LocationMatch로 옮길지 정합니다.

에러 로그에 남은 것

403이 나면 아파치 에러 로그에 client denied by server configuration 한 줄이 남습니다. 차단 후 9월 17일 새벽까지 이 줄이 5,070개 쌓였고, 문서 루트별로 나누면 이 워드프레스 다중 사이트가 724건, 다른 사이트들이 97~731건씩입니다. 공격 대상이 특정 사이트가 아니라 서버의 모든 호스트 이름이라는 뜻이고, fail2ban 잼이 161일 동안 0건이었던 이유를 봤을 때처럼 이 줄을 세는 것이 IP 차단 규칙보다 유용합니다. 없는 PHP 파일을 찾는 Primary script unknown은 차단 전후 비슷한 속도로 쌓이고 있어 이번 설정과 무관합니다.

정리

  • .git 차단은 요청을 막았다기보다 스캐너의 두 번째 단계를 없앴습니다. 첫 파일이 403이면 객체 파일 2만 건이 따라오지 않습니다.
  • 스캐너 IP 수는 변하지 않습니다. 막아도 매일 같은 수가 와서 첫 파일을 찔러 보고 갑니다. 그 비용은 IP당 3~4건, 199B짜리 응답이라 무시할 수 있습니다.
  • .env는 하위 폴더 경로 때문에 74%가 여전히 404이고, 그중 1,697건은 워드프레스가 55KB 페이지를 만들어 응답했습니다. 파일 이름 규칙으로는 부족합니다.

측정 방법

지난 글과 같은 접속 로그 다섯 개를 파이썬으로 파싱하되, 설정 적용 시각 2026-09-12 15:25(서버 시간, KST) 기준으로 앞뒤 96시간만 남겼습니다. 앞 창은 9월 8일 15:25부터, 뒤 창은 9월 16일 15:25까지입니다. .git 요청은 경로에 /.git이 든 것, .env 요청은 /.env가 든 것으로 잡았고, 워드프레스가 렌더링한 404는 응답 크기 1KB 이상으로 구분했습니다. IP별 요청 순서는 같은 IP의 줄을 시각순으로 늘어놓고 첫 .git 요청 바로 다음 줄을 본 것입니다. 응답 크기와 시간은 서버 안에서 curl --resolve로 kilho.org에 직접 요청해 잰 값입니다. 에러 로그는 9월 13일 로테이션 전후 두 파일에서 client denied 줄을 세고 경로에 든 문서 루트로 나눴습니다.

Similar Posts

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다