[Apache] 악성 봇과 크롤러 차단하기 (.htaccess)

By | 2024-02-03

직접 리눅스 서버를 구축하여 워드프레스 블로그를 운영하다 보면 광고댓글, 악성댓글과 싸우게 된다. 하지만 이 싸움에서 이기고 나니 다시금 악성 봇과 웹 크롤러들과 싸우는 2차 대전이 벌어졌다. 하지만 이젠 그 싸움이 그다지 어렵지 않다. 광고댓글과 악성댓글을 작성하는 IP를 .htaccess 파일에서 차단하듯 새로운 룰을 적용하여 차단하면 된다. 다만 악성봇과 웹크롤러들은 IP로 차단하기는 어렵다.

Access.log를 분석해 보면 User-Agent에 봇이나 웹 크롤러의 정보가 보이는데 광고댓글이나 악성댓글이 대부분 한두개의 IP에서 들어와 댓글을 달고 도망가는 것과는 달리 훨씬 더 많은 IP에서 출몰하는 차이점이 있다.

Access log 파일에서 악성봇과 웹크롤러 정보 수집하기

.htaccess의 접근통제 정책을 수립하기 위해서는 웹사이트 또는 블로그의 각 URL(포스트)에 접근하는 봇과 크롤러의 이름을 수집해야 한다. 이 정보는 Apache 웹서버의 access.log 파일을 분석해서 수집해야 한다.

일반적으로 우분투 리눅스에서 Apache 2.4 버전의 Access Log는 /var/log/apache2 디렉토리에 access.log 라는 파일에 실시간으로 저장된다. 봇(Bot)이 블로그 또는 웹사이트에 방문한 경우 다음과 같이 access.log에 기록된다.

주황색이 바로 봇(Bot)의 이름이다. Googlebot, bingbot과 같은 검색엔진의 봇(Bot)은 블로그의 포스트나 웹사이트의 페이지를 가져가 검색을 돕기 위한 목적으로 사용하기 때문에 착한(?) 봇(Bot)이다. Applebot 이나 화면에는 없지만 AmazonBot등은 인공지능의 학습을 위해 데이터를 수집해가는 봇들이다.

악성 봇(Bot)이나 도움이 되지 않는 봇(Bot)은 바로 proximic 이나 AhrefsBot 등 정체를 알 수 없는 이름의 봇(Bot)들이다. 이런 봇들은 쓸데없이 트래픽만 유발시키기에 차단하는 것이 좋은 그런 봇(Bot)이다.

봇의 방문을 차단하기 위해서는 이 봇(Bot)의 이름을 기준으로 차단하도록 .htaccess에 룰을 정의해주면 된다.

봇(Bot)과 크롤러(Crawler)의 이름으로 접근을 차단하는 룰(.htaccess)

봇과 크롤러의 이름으로 접근을 차단하도록 .htaccess에 룰을 정의할 수 있는데 IP를 기준으로 차단하는 것 처럼 접근을 원천적으로 차단할 수는 없다. 다만 온전한 포스트나 웹페이지를 응답하는 200 응답이 아니라 404 Not Found 에러를 응답하도록 설정한다.

.htaccess에 다음과 같은 룰을 추가한다.

# Apache access log의 User-Agent에 기록되는 Bot, Crawler 기준으로 거부
RewriteCond %{HTTP_USER_AGENT} ^.(ClaudeBot|Bytespider|GrapeshotCrawler|Amazonbot|proximic).$ [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.(SemrushBot|DataForSeoBot|AhrefsBot|ias_crawler|peer39_crawler).$ [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.(TTD-Content|admantax.com).$ [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.(ias-or|ias-va|ias-ie|ias-sg|ias-ie|ias-au|CriteoBot).$ [NC]
RewriteRule .* - [R=404,L]

다음 화면은 위의 룰이 Document_Root의 디렉토리에 위치한 .htaccess에 적용된 화면이다.

접근이 차단된 봇(Bot)과 크롤러(Crawler)의 Access log

앞의 룰을 적용한 다음 Apache 웹서버를 재시작하고 나면 봇과 크롤러가 방문했을 때 다음과 같이 404 Not Found 에러를 응답하는 것을 볼 수 있다.

이제 봇과 크롤러의 싸움에서도 이길 수 있다.

답글 남기기

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