Jaynarol Blog

Docker : แก้ปัญหา IP เมื่อ CloudFlare + HAProxy + Apache

เคยได้ยินคนบอกว่าปัญหาด้าน IT มักมีคนเจอก่อนและแก้ไว้หมดแล้ว เพียงแค่เสริชให้ถูกคีย์แค่นั้น แต่ไม่ใช่กับเคสนี้ เพราะเสริชแล้วไม่เจอเลยต้องลองผิดลองถูกเองหลายชั่วโมงเลย – -*

เรื่องของเรื่องคือระบบเดิมใช้งาน CloudFlare > Apache ทีนี้พอเอา HAProxy  มาคั่น (CloudFlare + HAProxy + Apache)  ปัญหาเรื่อง IP ก็เกิดทันที…

 

ปัญหา และ ความต้องการ

  1. IP ที่ Apache ได้รับทั้งหมดเป็น IP ของ HAProxy แต่เราอยากได้ IP Client จริงๆ
  2. จากข้อที่ 1 ทำให้ Apache เก็บ Logs ผิด IP ด้วย
  3. ไม่ต้องการไปแก้ที่ Application มันควรจะยืดหยุ่นที่โครงสร้างมากกว่า
  4. Application ต้องได้รับ IP Client เสมอ ไม่ว่าจะผ่าน CloudFlare หรือไม่ (เผื่ออนาคตถอด CloudFlare ออก)
  5. ต้องหาวิธีที่ให้ HAProxy มันแยกแยะเองได้ ว่าอันไหน CloudFlare อันไหน Client
  6. HAProxy ต้องพร้อมอัพเดทตัวเองได้ตลอด หาก CloudFlare เปลี่ยนหรือเพิ่มวง IP ใหม่

 

แก้ปัญหา

ตอนแรกที่เห็นโจทย์มันดูไม่เห็นยากเลยสักนิด แต่หลังจากผ่านไป 3 ชั่วโมงจนเกือบถอดใจบอกได้เลยว่ายังมีโจทย์เล็กๆที่มันแอบอยู่เยอะมากจนสุดท้ายมาลงตัวด้วยวิธีนี้

 

  • ขั้นตอนแรก สร้าง docker-compose.yml เพื่อเข้าใจภาพรวมของระบบ
 

  • สืบทอดและสร้าง Image HAProxy ใหม่เป็นของเราเอง เพิ่มคำสั่งให้มันไปโหลด IP ทั้งหมดของ CloudFlare มาเก็บไว้ที่ /home/cf-ip (สำหรับใช้ตอนรัน Container)
 

  • เพิ่มการตั้งค่า HAProxy ใน Dockerfile ให้มันตรวจสอบ IP ที่ Request เข้ามาว่าตรงกับ List ของ CloudFlare หรือไม่ ถ้าตรงให้ดึง IP จาก header CF-Connecting-IP มา แต่ถ้าไม่ให้ใช้ IP Client แทน จากนั้นนำค่าเขียนลง header X-Real-Ip และแนบไปกับ Request ที่ส่งไปให้ Apache
 

  • สืบทอดและสร้าง Image Apache+PHP ใหม่เป็นของเราเองและเปิดให้ใช้งาน mod_remoteip
 

  • เพิ่มการตั้งค่า Apache ใน Dockerfile ให้มันโหลด config ต่างๆของเราเข้าไปใช้งาน
 

  • ในไฟล์ remoteip.conf กำหนดให้ Apache ใช้งาน IP จาก Header X-Real-Ip แทน และเชื่อถือเมื่อถูกส่งมาจาก HAProxy เท่านั้น  (HAProxy ชื่อ host คือ lb ตามที่ตั้งไว้ใน docker-compose)
 

  • เพิ่มการตั้งค่า Apache ใน Dockerfile โดยให้แก้ไข /etc/apache2/apache2.conf ของ image เพื่อให้ apache ใช้ IP จาก mod_remoteip ในการบันทึกลง Logs ด้วย
 

สรุป

สามารถโหลดและดูไฟล์ทั้งหมดได้ที่ jaynarol-blog/docker-cf-haproxy-apache นะครับ ผมมัดเป็น docker-compose ไว้ให้สามารถลองรันด้วยคำสั่ง docker-compose up -d -build ได้เลย

แล้วพบกันใหม่ สวัสดีครับ