

เมื่อเว็บเริ่มมี reverse proxy หรือ CDN อยู่ข้างหน้า การเชื่อมต่อที่มาถึงแอปจะผ่านตัวกลางก่อน IP ที่เห็นจาก connection จึงอาจเป็นของ proxy ที่ส่งคำขอเข้ามา ไม่ใช่เครื่องของคนหรือบอทที่เริ่มขอหน้าเว็บจากภายนอก
ถ้าต้องใช้ข้อมูลนี้เพียงดูว่าระบบหลังบ้านคุยกับเครื่องไหน ก็อาจยังตรงความต้องการ แต่เมื่อนำไปนับผู้ใช้ ตรวจตัวตนบอท หรือจำกัดจำนวนคำขอ ความเข้าใจผิดเพียงจุดเดียวอาจทำให้ทุกคนดูเหมือนมาจาก IP เดียวกัน หรือยอมรับค่าที่ผู้ส่งใส่มาเองได้
จึงควรเริ่มจากแผนเส้นทางของ request ครับ แล้วค่อยกำหนดว่าข้อมูลใดเชื่อถือได้จากตัวกลางใด การอ่าน field ที่ชื่อเหมือน client IP ไม่ได้ยืนยันแหล่งกำเนิดของข้อมูลนั้นโดยตัวมันเอง
ลองสมมติเส้นทางจากผู้ใช้ไป CDN แล้วไป reverse proxy ก่อนถึงแอป ในแต่ละช่วง connection จะมีต้นทางและปลายทางของช่วงนั้น แอปที่เชื่อมกับ reverse proxy จึงรู้แน่นอนอย่างหนึ่งว่า peer ของ connection นี้เป็น reverse proxy ตามที่ระบบเครือข่ายเห็น
ส่วนข้อมูลต้นทางก่อนผ่านตัวกลางอาจถูกส่งมาใน header เช่น X-Forwarded-For หรือ header เฉพาะของบริการ ข้อมูลแบบนี้ต้องพึ่งสัญญาว่าตัวกลางตั้งค่าอย่างไร รับค่าจากผู้ส่งเดิมมาหรือไม่ และจะเพิ่มหรือเขียนทับส่วนไหนเมื่อส่งต่อ

หากไม่มีการกำหนดขอบเขตความเชื่อถือ ผู้ส่งภายนอกก็อาจแนบ header ชื่อเดียวกันมาได้ การใช้ค่าที่อยู่ซ้ายสุดหรือค่าที่ชื่อดูตรงโดยไม่ตรวจเส้นทาง จึงอาจกลายเป็นนำข้อความที่ผู้ส่งควบคุมไปใช้เป็นตัวตนสำหรับการตัดสินใจ
แผนระบบควรบอกว่ามีทางเข้าผ่านตัวกลางกี่ทาง และ origin ยังรับการเชื่อมต่อตรงจากอินเทอร์เน็ตได้หรือไม่ เพราะถ้ามีทางข้าม CDN เข้ามาได้ เงื่อนไขที่คิดว่าทุก request ถูกตรวจและจัด header โดย CDN แล้วก็จะไม่จริงสำหรับทางนั้น
ใน NGINX มี real IP module สำหรับแทนข้อมูลที่อยู่ของ client ด้วยค่าที่ส่งมาใน header ที่กำหนด โดย set_real_ip_from ใช้ระบุแหล่งที่เชื่อถือได้ว่าเป็นผู้ส่งข้อมูลแทนที่ถูกต้อง และ real_ip_header ใช้เลือกว่ารับจาก field ใด
จุดสำคัญคือขอบเขตที่ระบุให้เชื่อถือควรตรงกับ proxy จริง ไม่ใช่เปิดทุกที่อยู่เพื่อให้เริ่มเห็นตัวเลข IP ต่างกัน เพราะการตั้งแบบกว้างเกินไปจะทำให้ผู้ส่งที่ไม่ได้ผ่าน proxy ที่ควบคุมอยู่มีโอกาสกำหนดค่าที่นำไปใช้ต่อได้
หากมีหลาย proxy ต้องอ่านพฤติกรรมการไล่ chain ให้ตรงด้วย NGINX แยกกรณีเปิด real_ip_recursive โดยพิจารณาที่อยู่ที่ไม่อยู่ในกลุ่ม trusted ตามกติกาของโมดูล จึงไม่ควรย่อเป็นสูตรว่าเลือก IP ตัวแรกเสมอโดยไม่สนใจว่ามีตัวกลางใดรับรองข้อมูลอยู่
การใช้ header เฉพาะของ CDN ก็ต้องตรวจทั้งเอกสารผู้ให้บริการกับเงื่อนไขทางเข้า origin ถ้า header นั้นถูกยอมรับจากการเชื่อมต่อตรงของใครก็ได้ ก็ยังไม่ได้บังคับว่าเป็นค่าที่ CDN สร้างมาให้จริง เพียงเปลี่ยนชื่อ field ที่เสี่ยงถูกอ้างเท่านั้น
เมื่อแทน client address แล้ว ควรมีทางตรวจ peer เดิมกับค่าที่นำมาใช้ด้วย อย่าง NGINX มีตัวแปร realip_remote_addr เก็บที่อยู่เดิมไว้สำหรับโมดูลนี้ จึงช่วยแยกว่าค่าที่เปลี่ยนแล้วมาจากเส้นทางใด ไม่เหลือเพียง IP สุดท้ายโดยไม่รู้บริบท
Access log ควรระบุเวลา จุดที่เก็บ request ID และข้อมูลที่จำเป็นต่อการตามเส้นทาง โดยปกป้องรายละเอียดผู้ใช้กับ header ที่ละเอียดอ่อน การเก็บ header ทั้งหมดเผื่อไว้ก่อนอาจพารหัสลับกับ cookie เข้ามาใน log มากเกินจำเป็น

หากมีการส่ง log หลายชั้นไปเก็บรวมกัน ควรแยกชื่อ field ให้ชัด เช่น peer address, validated client address และข้อมูลอ้างอิงจากชั้นก่อน ไม่ตั้งทุก field ชื่อ ip แล้วนำมารวมเป็นชนิดเดียว เพราะระดับความเชื่อถือและหน้าที่ของมันต่างกัน
การเปลี่ยนค่าใน log ยังอาจกระทบกลไกอื่นที่อ่านตัวแปรเดียวกัน เช่น rate limit หรือการคัดกรองการเข้าถึง จึงควรตรวจเอกสารกับ configuration จริงว่าการแทน client address มีผลถึงส่วนใดบ้าง ไม่ถือว่าเป็นการเปลี่ยนหน้าตาข้อมูลสำหรับรายงานเพียงอย่างเดียว
การทดสอบในสภาพแวดล้อมแยกควรมี request ที่ผ่าน proxy ตามปกติ และ request จากแหล่งที่ไม่ได้อยู่ใน trusted list พร้อมใส่ header เลียนแบบไว้ด้วย ผลที่ต้องการคือค่าที่ใช้ตัดสินใจต้องไม่ถูกเปลี่ยนตามข้อความจากทางที่ไม่ได้รับความเชื่อถือ
กรณีที่มีหลาย hop ให้ตรวจทีละจุดว่าตัวกลางรับค่าใดเข้ามาและส่งอะไรต่อ ไม่ใช้เพียง request สุดท้ายที่ออกมาดูถูกต้องเป็นหลักฐานว่าไม่มีทางปลอมค่า เพราะบางเส้นทางอาจถูกต้องตามปกติแต่ยังเปิดรับ header จากทางข้ามอยู่
ควรตรวจ IPv4 กับ IPv6 ตามที่ระบบรองรับ รวมถึงการเปลี่ยนเส้นทางเมื่อมี proxy สำรอง หากผู้ให้บริการเปลี่ยนช่วง IP ที่ใช้ส่งต่อ ก็ต้องมีวิธีอัปเดตแหล่ง trusted ตามข้อมูลทางการ โดยทบทวนว่ารายการนั้นเป็นช่วงสำหรับบริการที่ใช้งานจริง
ตัวอย่างเหล่านี้เป็นแนวตรวจความถูกต้องของการตั้งค่า ไม่ใช่คำแนะนำให้ส่ง traffic ทดสอบไปยังระบบภายนอกที่ไม่ได้ดูแล และยังไม่ได้หมายความว่า proxy ของ CommandEng ได้ถูกเปลี่ยนหรือทดสอบตามรายการนี้แล้ว
แม้ได้ที่อยู่ต้นทางตามระบบ proxy อย่างถูกต้อง IP ก็ยังไม่ได้แทนคนหนึ่งคนเสมอไป ผู้ใช้หลายรายอาจใช้เครือข่ายออกอินเทอร์เน็ตร่วมกัน ส่วนผู้ใช้รายเดียวอาจเปลี่ยนเครือข่ายหรือใช้ที่อยู่หลายค่าได้ จึงต้องเลือกความหมายให้เหมาะกับสิ่งที่จะวัด
สำหรับการตรวจบอท IP เป็นข้อมูลประกอบการตรวจยืนยันจากเอกสารผู้ให้บริการ ไม่ใช่เพียงเห็นช่วงที่คุ้นแล้วตั้งชื่อเอง การตรวจ reverse DNS ต้องมีขั้นยืนยันกลับตามวิธีที่เจ้าของบอทกำหนด และควรเก็บว่าใช้วิธีใดตรวจ ณ เวลานั้น
หากนำไปจำกัดคำขอ ต้องดูผลต่อผู้ใช้ที่แชร์ทางออกเครือข่ายด้วย และอาจต้องใช้ตัวตนของบัญชีหรือขอบเขตงานร่วมกันตามลักษณะระบบ การได้ IP ที่ถูกต้องช่วยให้ข้อมูลตั้งต้นดีขึ้น แต่ไม่ได้เลือกนโยบายที่เหมาะสมแทนเรา
เมื่อ request ผ่าน proxy ข้อมูลที่แอปเห็นต้องถูกอ่านตามเส้นทางจริง ทั้ง peer ของ connection และ client address ที่ตัวกลางส่งต่อ การกำหนดแหล่งที่เชื่อถือได้ให้แคบ ตรวจ chain และเก็บบริบทของค่า ช่วยให้ใช้ log กับการตัดสินใจต่อได้ตรงความหมายมากขึ้น โดยยังรักษาข้อจำกัดว่า IP เป็นข้อมูลเครือข่าย ไม่ใช่ตัวตนของคนหรือบอทที่ยืนยันแล้วในตัวเอง