แก้ปัญหา REMOTE_ADDR ใน Reverse Proxy
สวัสดีครับ วันนี้จิบเบียร์แล้วก็มานั้งทบทวนเรื่องงานที่ทำ พอดีมีเรื่องเล็กๆน้่อยๆ ที่ผมเองทำและน่าจะเป็นประโยช์กับเพื่อนๆ เกี่ยวกับการตั้ง Reverse Proxy กับปัญหา เรื่อง IP ที่ show ใน app ของเรา
ปกติเวลาเราเขียน Apps หรือ พวกฟรี Webboard ทั้งหลายจะมีการ Check IP จาก
$_SERVER['REMOTE_ADDR'] และ $_SERVER['HTTP_X_FORWARDED_FOR'] หากเจอตัวแปล HTTP_X_FORWARDED_FOR ระบบจะทำการ Record IP จาก HTTP_X_FORWARDED_FOR ด้วย แต่หากว่าบางโปรแกรมที่เขียน จะเก็บแค่ REMOTE_ADDR ทำให้ IP ที่แสดงในโปรแกรมของเรา เป็น IP ของ Reverse Proxy แทน
Client IP: 203.146.1.1
Proxy IP: 192.168.1.100
Web IP: 192.168.1.1
[Client] ===> [Revert Proxy] ===> [Web Server]
เมื่อ Web Server ได้รับ Request Header จะได้ดั่งนี้
$_SERVER['REMOTE_ADDR'] = 192.168.1.100
$_SERVER['HTTP_X_FORWARDED_FOR'] = 203.146.1.1
ทางแก้ง่ายนิดเดียวครับ แก้ที่ System ไม่ต้องไปขอร้องให้ Programmer แก้ไขโค๊ดแต่อย่างใด ทางออกอยู่ที่ PHP ครับ โดย PHP จะมี Parameter อยู่ 2 ตัวคือauto_prepend_file และ auto_append_file
auto_prepend_file จะกำหนดว่า ก่อนที่จะรันไฟล์ php ทุกๆครั้ง จะทำการรันไฟล์นี้ก่อน ส่วน auto_append_file คือเมื่อทำการรันไฟล์ php ใดๆเสร็จแล้ว จะมารันไฟล์ ที่เรากำหนด เมื่อเรารู้ดั่งนี้แล้ว เ้ราก็มาดูโค๊ดแก้ปัญหาเรื่อง Rever Proxy & REMOTE_IP ได้เลยครับ
1. ให้เราไปกำหนดที่ php.ini ใส่พารามิเตอร์ auto_prepend_file “/etc/php-prepend.php”
2. แก้ไขไฟล์ /etc/php-prepend.php
<? $real_ip = session_getip(); $ip = $_SERVER["REMOTE_ADDR"]; $_SERVER["REMOTE_ADDR"] = $real_ip; unset($_SERVER['HTTP_X_FORWARDED_FOR']); function session_getip() { if ($_SERVER["HTTP_CLIENT_IP"]) { return $_SERVER["HTTP_CLIENT_IP"]; } foreach (explode(",",$_SERVER["HTTP_X_FORWARDED_FOR"]) as $ip) { if (trim($ip)) { return $ip; } } if ($_SERVER["HTTP_X_FORWARDED"]) { return $_SERVER["HTTP_X_FORWARDED"]; } elseif ($_SERVER["HTTP_FORWARDED_FOR"]) { return $_SERVER["HTTP_FORWARDED_FOR"]; } elseif ($_SERVER["HTTP_FORWARDED"]) { return $_SERVER["HTTP_FORWARDED"]; } elseif ($_SERVER["HTTP_X_FORWARDED"]) { return $_SERVER["HTTP_X_FORWARDED"]; } else { return $_SERVER["REMOTE_ADDR"]; } } ?>
Code ดั่งกล่าว จะทำการ ดึง IP ที่ HTTP_X_FORWARDED มาไว้ยัง $real_ip และทำการกำหนดให้ REMOTE_ADDR = $real_ip ทำให้ app ทั่วไปทีเราเขียนขึ้น ไม่ต้องทำการแก้ไข Code แต่อย่างใด
ป.ล. ส่วนของ prepend และ append สามารถนำไปใช้งานได้หลายรูปแบบมากกว่านี้เอาไว้โอกาศหน้า ผมจะมาเขียนบอกเล่าให้เพื่อนๆ ได้อ่านต่อไปครับ
Tags: PHP, Reverse Proxy
February 19th, 2009 at 1:19 pm
แจ่มจริงๆ สำหรับเทคนิค ดีๆ ครับพี่อัท
เรียนรู้ unix
March 2nd, 2009 at 1:39 am
สอบเสร็จเดี๋ยวตามอ่านให้หมดทุกโพสเลยครับ
อยากรู้ๆ
เก็บประสบการณ์ๆ
^^
March 26th, 2009 at 2:35 pm
ขอบคุณมากครับ ที่แนะนำวิธีแก้ปัญหาให้ อิอิ
September 30th, 2009 at 2:35 am
Blog นี้ช่วยแก้ปัญหาผมสองเรื่องแล้ว ขอบคุณนะครับ
March 2nd, 2010 at 4:29 pm
มาเจอโดยบังเอิญ แต่เป็นแหล่งความรู้ที่ดีมากครับ