만족
[PHP] 아이피 정보 조회 및 해외 아이피 차단 본문
[PHP] 아이피 정보 조회 및 해외 아이피 차단
Backend/PHP Satisfaction 2022. 1. 13. 18:42현재 운영중인 서비스에서 VPN으로 아이피를 해외로 돌려 악성 댓글을 작성하는 경우가 포착되었다.
따라서 요청 아이피를 확인해 해외 아이피인 경우 일부 기능을 사용할 수 없도록 할 것이다.
클라이언트 아이피 가져오기
function getClientIP() {
$ipaddress = '';
if ($_SERVER['HTTP_CLIENT_IP']) {
$ipaddress = $_SERVER['HTTP_CLIENT_IP'];
} else if ($_SERVER['HTTP_X_FORWARDED_FOR']) {
$ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else if ($_SERVER['HTTP_X_FORWARDED']) {
$ipaddress = $_SERVER['HTTP_X_FORWARDED'];
} else if ($_SERVER['HTTP_FORWARDED_FOR']) {
$ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
} else if ($_SERVER['HTTP_FORWARDED']) {
$ipaddress = $_SERVER['HTTP_FORWARDED'];
} else if ($_SERVER['REMOTE_ADDR']) {
$ipaddress = $_SERVER['REMOTE_ADDR'];
}
return $ipaddress;
}
이 코드는 요청 헤더에서 요청 클라이언트의 IP를 리턴하는 코드이다.
IP 정보 조회하기
https://ipinfo.io/account/home
ipinfo에서 해당 기능을 무료로 제공한다. (월 50,000건까지)
회원가입을 완료하면(결제 수단 등록이 필요하지 않다), 토큰을 발급받는다.
별도 로직 작성 없이 모듈을 다운로드하여 사용할 수도 있다.
다만 이 포스트에서는 사용하지 않고, 직접 curl 코드를 작성해 사용할 것이다.
class HTTPResponse {
public $code;
public $response;
public $url;
public $info;
public $raw;
public function __construct($ch) {
$temp = curl_exec($ch);
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
// $header = substr($data, 0, $headerSize);
$this->response = substr($temp, $headerSize);
$this->code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$this->url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
$this->info = curl_getinfo($ch);
$this->raw = $temp;
curl_close($ch);
}
public function printInfo() {
var_dump($this->info);
// echo $this->code;
// echo $this->url;
// echo $this->response;
// echo $this->info;
}
}
class Curl {
public static function get($url, $params, $header = array('Accept: application/json', 'Content-Type: application/json')) {
//$query= http_build_query(Curl::parseParams($params));
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url . '?' . $params);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
//echo curl_errno($ch);
return new HTTPResponse($ch);
}
}
Curl 실행 시 위 코드를 사용할 것이다.
이제 발급받은 토큰과, 가이드를 참조하여 IP의 정보를 조회해 보자.
//...
$response= Curl::get('https://ipinfo.io/'.$ip,"token=YOUR_TOKEN");
if($response->code!= 200){
//요청 횟수 초과 및 검증 서버 다운
}
$response= json_decode($response->response);
var_dump($response);
//...
결과는 아래와 같다.
array(9) { ["ip"]=> string(15) "221.146.186.213" ["city"]=> string(5) "Seoul" ["region"]=> string(5) "Seoul" ["country"]=> string(2) "KR" ["loc"]=> string(16) "37.5783,127.0946" ["org"]=> string(20) "AS4766 Korea Telecom" ["postal"]=> string(5) "02260" ["timezone"]=> string(10) "Asia/Seoul" }
여기에서 country값이 KR이면 한국이고, 다른 값이면 해외로 취급한다.
따라서 아래 로직을 추가하여 해외 아이피일 경우 요청을 드랍시킬 수 있다.
//...
$response= Curl::get('https://ipinfo.io/'.$ip,"token=YOUR_TOKEN");
if($response->code!= 200){
//요청 횟수 초과 및 검증 서버 다운
}
$response= json_decode($response->response);
if($response['country'] != 'KR'){
//해외 아이피
}else{
//한국 아이피
}
//...
이 로직을 모듈화 시켜보자.
function isAllowedCountryIP($ip){
$response= Curl::get('https://ipinfo.io/'.$ip,"token=YOUR_TOKEN");
if($response->code!= 200){
//요청 횟수 초과 및 검증 서버 다운
return true;
}
$response= json_decode($response->response);
if($response['country'] != 'KR'){
return false;
}
return true;
}
이렇게 하면 isAllowedCountryIP에 아이피를 전달했을 때,
아이피 정보를 조회할 수 없거나 한국 아이피인 경우 true, 이외에는 false를 리턴하게 된다.
이제 해외 아이피가 사용하지 못하게 할 엔드포인트로 이동해,
isAllowedCountryIP(getClientIP()) 를 사용하여 false일 경우
403으로 응답하여 해당 엔드포인트를 사용할 수 없게 만들 수 있다.
//해외 아이피를 차단할 엔트포인트 로직
//...
if(!$isAllowedCountryIP(getClientIP())){
//해외 아이피 감지
http_response_code(403);
exit();
}
//원래의 로직 실행
//...
'Backend > PHP' 카테고리의 다른 글
[PHP] 텔레그램 봇 API로 서버 주요 알림 받아보기 (0) | 2021.11.06 |
---|---|
[PHP] CPU/메모리/디스크 사용량 로드하기 (0) | 2021.04.25 |
[PHP] Magic Quote는 정말 SQL Injection을 완벽 방어할까? (0) | 2020.10.26 |
[PHP] 즉시 실행 가능한 웹 코드 에디터 (0) | 2020.10.25 |