[อยากจะรู้] อยากได้ Client IP Address ไปใช้งานใน PHP Web Application ทำยังไงดี

เรื่องมีอยู่ว่าลูกค้ามี PHP Web Application อยู่หลัง nginx และแถมยังมี Load Balancer อีกโดยทั้งหมดอยู่บน GCP โดยมี Architecture ตามรูปด้านล่าง

ผมปรากฎว่าลองทดสอบ Web Application แล้วไม่ได้ผลตามที่ต้องการเนื่องจากระบบไม่สามารถตรวจสอบ Client IP Address ได้ ลองตรวจสอบผ่าน phpinfo() แล้วก็เจอว่า

ค่า HTTP_X_FORWARDED_FOR ก็มีค่า Client IP Address กับ Load Balancer IP Adress (58.8.173.125, 35.244.216.191) มาด้วยกัน และค่า REMOTE_ADDR ก็มีค่าเป็น IP Address ผ่านในจาก Load Balancer (130.211.2.195)

ดู Logs บน Server ก็จะเห็น Nginx Logs แสดงการเรียกมาจาก IP Address ผ่านในจาก Load Balancer เหมือนกัน

แล้วจะทำยังไงดีเนี่ย ก็เลยลองหาข้อมูลไปเรื่อยๆ จนเจอว่าลองปรับ Nginx น่าจะง่ายที่สุด เพราะ Load Balancer เราก็ยังไม่เชี่ยวว่าปรับอะไรได้บ้าง (จริงๆ Nginx ก็ไม่เชี่ยวแต่น่าจะงมๆ ไปได้อยู่ ฮ่าๆ) แล้วในที่สุดก็มาเจอ config นี้ก่อน

set_real_ip_from 0.0.0.0/0;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

โดยให้เพิ่มเข้าไปในส่นของ location เพื่อเป็นการบอกให้ Nginx ตั้งค่า Real IP จากทุกๆ เน็ตเวิร์คที่วิ่งเข้ามา (0.0.0.0/0) โดยกำหนดค่า IP Address ที่ได้ไปที่ Header X-Forwarded-For และให้เช็ค IP Address ที่ได้รับมาตรวจสอบว่าค่า Original Client Address อยู่ใน List ที่เรากำหนดจาก set_real_ip_from ไว้ก็จะเอาค่านั้นมาใช้งาน

เมื่อเราทำการเพิ่ม Config ในส่วนนี้เข้าไปแล้วลองดูผลซิว่าเป็นอย่างไรบ้าง

ค่า REMOTE_ADDR เปลี่ยนเป็น Client IP Address แล้วแต่ HTTP_X_FORWARDED_FOR ยังมีค่า Client IP Address และ Load Balancer อยู่

Logs บน Nginx Logs แสดง Client IP Address ได้ถูกต้องแล้ว

ยังเหลือ HTTP_X_FORWARDED_FOR ก็หาข้อมูลอีก และก็มาเจอ config อีกชุดที่ต้องเพิ่มเข้าไปโดยมีข้อแม้ว่าต้องอยู่หลัง include fastcgi_params;

if ($http_x_forwarded_for ~ "^(\d+\.\d+\.\d+\.\d+)") {
set $realip $1;
}
fastcgi_param HTTP_X_FORWARDED_FOR $realip;

หลังจากที่เพิ่มเข้าไปแล้ว ลองเช็คอีกครั้ง…

เย้ในที่สุดก็ได้ที่ตามต้องการเป็นอันปิดเคส นอนหลับสบายใจ

สุดท้ายแล้วหากท่านไหนหลงเข้ามาอ่านแล้วเห็นเป็นประโยชน์ก็สามารถนำไปต่อยอดได้เลย หรือหากมีคำแนะนำดีๆ ก็สามารถบอกกล่าวให้ทราบได้เช่นกันครับ

Ref: http://nginx.org/en/docs/http/ngx_http_realip_module.html

Ref: https://stackoverflow.com/questions/25929599/nginx-replace-remote-addr-with-x-forwarded-for

นายช่างระบบระบบคอมพิวเตอร์ทั้วๆ ที่ชอบทดลอง และเรียนรู้สิ่งใหม่ไปเรื่อยๆ

นายช่างระบบระบบคอมพิวเตอร์ทั้วๆ ที่ชอบทดลอง และเรียนรู้สิ่งใหม่ไปเรื่อยๆ