아래 스크립트를 사용하면서 생기는 문제나 피해에 대해서는 일절 책임을 지지 않습니다. 사용하시기 전에 반드시 DB 백업을 하실 것을 권장합니다.
태터툴즈 '묻고답하기' 게시판에 올린 글이다.
클릭
하지만 아래에 좀 더 자세하게 정리를 해 보았다.
스팸 리플들은 보통 수백개가 달린다. 손으로 지우기는 너무 많은 개수다. 그래서 나는 달린 스팸 리플들을 분석하기 시작했다.
1. 이것은 사람이 다는 것이 아니다. 아마도 봇이 주소를 긁으면서 목록을 갱신하며 일정시간마다 스팸 리플들을 블로그에 수백개씩 단다.
2. 이름과 본문은 크게 중요하지 않은 것 같다. 랜덤한 텍스트를 이름과 본문에 넣는데 중요한 것은 홈페이지다. 수백개의 홈페이지 중 열 개 정도를 보니 다음과 같은 형식으로 쓰여져 있었다.
http://어쩌구저쩌구.blah.com/
위에서 중요한 부분은 blah.com 이다. 더 이상 저 홈페이지의 광고 스팸이 올라오지 못하도록 태터 스팸 막기에서 '홈페이지에 이 문자열이 있으면 스팸으로 인식합니다'에 blah.com 을 넣어준다. 일단 스팸은 멈춘다. IP나 이름, 본문이 계속 바뀌는 경우가 많은 것 같으므로 위와 같은 방법이 조금은 더 효율적일 것이다.
3. 이제 스팸리플들을 지울 차례다. 나는 mysql 쿼리문을 날릴 줄 알고, php를 작성해서 스크립트를 작성할 수 있다. 따라서 나는 아래와 같은 php 코드를 작성해서 확장자를 php로 한 다음 웹브라우저가 접근할 수 있는 곳에 저장했다.
이 코드는 인터넷 익스플로러에서 보면 좁은 폭 때문에 코드를 읽기가 힘들어지는데, 긁어 붙여서 따로 봐도 좋다.
<? $DB_ADDRESS = "localhost"; $DB_USER = "db_user"; $DB_PASSWORD = "db_password"; $DB_NAME = "db_name";
$fd = mysql_connect( $DB_ADDRESS, $DB_USER, $DB_PASSWORD ) or die( "cannot connect" ); print( "connection success" ); print( "<br />" );
$result = mysql_query( "use $DB_NAME" ) or die( "invalid use of DB" );
$contentTableName = "포스팅들이 들어 있는 테이블 이름을 입력하세요"; $replyTableName = "리플들이 들어 있는 테이블 이름을 입력하세요"; $spamHomepageWord = "스팸 홈페이지 문자열을 입력하세요";
mysql_query( "delete from $replyTableName where homepage like "%$spamHomepageWord%"" ) or die( "delete spam reply failed." );
$result = mysql_query( "select no from $contentTableName" ) or die( "Table name selection failed." );
while( $row = mysql_fetch_array( $result, MYSQL_NUM ) ) { $countResult = mysql_query( "select count(pno) from $replyTableName where pno=$row[0]" ) or die( "Counting reply count failed." ); $countRow = mysql_fetch_array( $countResult, MYSQL_NUM ); mysql_query( "update $contentTableName set rp_cnt = $countRow[0] where no = $row[0]" ) or die( "Resetting reply count failed." ); }
print( "Spam removed" );
mysql_close( $fd ); ?>
1) 처음에 보이는 DB_ADDRESS, DB_USER, DB_PASSWORD, DB_NAME 은 호스팅 업체의 서버 설정에 맞게 고쳐주면 된다.
2) 중간에 보이는 contentTableName, replyTableName, spamHomepageWord는 다음과 같다.
contentTableName: 블로그에 쓴 포스팅들이 저장된 테이블이다.
replyTableName: 블로그에 달린 리플들이 저장된 테이블이다.
spamHomepageWord: 위에서 말한 "blah.com" 을 쓰면 된다.
간략히 소스 설명을 하자면...
a. replyTableName 테이블에서 homepage 필드 에 spamHomepageWord 단어를 포함한 리플을 지운다.
b. 리플이 정상적으로 지워졌으나 블로그에서 보면 리플이 지워지기 전과 같은 개수로 리플이 표시된다. 어떤 포스트에 댓글이 전부 6개 달려 있었고 그 중 하나가 스팸 리플이었다면, 스팸 리플이 지워지고 보이는 리플은 5개밖에 없지만 여전히 리플 개수는 6으로 표시된다는 것이다.
이것은 contentTableName 테이블에서 리플 개수를 직접 가지고 있기 때문이다. 지워진 리플의 개수가 반영이 되지 않았기 때문에 따라서 mysql DB에 직접 쿼리를 날려서 수정을 해야 한다.
참고로 내 태터는 0.9x 버전 때부터 쓰다가 Classic RC3를 거쳐 현재는 Classic Official Release인데, 확인해 보지는 못했지만 공식 릴리즈 1.x부터는 데이터 복구 기능을 사용하면 개수가 제대로 맞춰진다고 한다. 그리고 어떤 버전의 태터는 테이블 구조가 다를 수 있고, 필드 이름이 다를 수 있기 때문에 위 코드를 수정해야 할지도 모른다. mysql_query 부분에서 사용된 homepage, no, pno, rp_cnt 등은 필드의 이름이고 다른 버전에서는 다를 수 있다.
php 코드를 웹에서 실행한 뒤 "Spam removed"라는 메시지가 나오면 스팸이 정상적으로 지워지고 개수가 제대로 나올 것이다. 다시 한 번 말하지만, 이 스크립트를 실행하기 전에 DB 백업 정도는 해 놓자. 이 코드를 사용함으로써 생기는 문제나 피해는 내가 책임지지 않을 것이고 책임질 수도 없으니... |