สวัสดีครับทุกคน! วันนี้อยากมาแชร์ประสบการณ์ลองทำอะไรเล่นๆ ที่เรียกว่า GRE tunnel เนี่ยแหละครับ คือเรื่องของเรื่องมันมีอยู่ว่า ผมอยากจะเชื่อมเน็ตเวิร์กสองที่เข้าด้วยกันแบบง่ายๆ ให้มันคุยกันได้เหมือนอยู่ใกล้ๆ กันเลย ก็เลยไปลองค้นๆ ดูว่ามีวิธีไหนบ้าง
ตอนแรกก็งงๆ นะครับ ไอ้ GRE เนี่ยมันคืออะไรวะ พอไปอ่านๆ ดูก็อ๋อ มันเหมือนเราสร้างท่อส่วนตัวขึ้นมาอีกท่อ ครอบทับบนอินเทอร์เน็ตที่เราใช้อยู่ปกติ ลองนึกภาพตามนะครับ เรามีถนนใหญ่ (อินเทอร์เน็ต) แล้วเราก็สร้างเลนพิเศษส่วนตัวของเราวิ่งบนถนนใหญ่นั่นแหละ ข้อมูลที่วิ่งในเลนพิเศษนี้ก็จะมองไม่เห็นรถคันอื่นบนถนนใหญ่

ประโยชน์ของมันก็คือ สมมติเรามีออฟฟิศสองที่ อยากให้คอมพิวเตอร์มันคุยกันได้เหมือนอยู่ใกล้ๆ กัน ทั้งๆ ที่อยู่คนละจังหวัดงี้ ก็ใช้เจ้านี่แหละช่วยได้ หรือบางทีอยากจะให้ traffic บางอย่างวิ่งผ่าน 加速器 แต่ไม่อยากตั้งค่า 加速器 ซับซ้อนบนทุกเครื่อง ก็ทำ GRE tunnel ไปหาปลายทางที่มี 加速器 อีกทีก็ได้
เอาล่ะ มาดูวิธีที่ผมลองทำกันเลยดีกว่า ผมใช้เครื่อง Linux สองตัวนะ สมมติชื่อ Server A กับ Server B ละกัน
ฝั่ง Server A (สมมติ Public IP คือ 1.1.1.1)
ผมก็เริ่มจากการสร้าง interface tunnel ขึ้นมาก่อนเลย คำสั่งที่ผมใช้ก็ประมาณนี้:
- เปิดใช้งาน module ip_gre ก่อน: ผมเช็คดูก่อนว่า kernel มันรู้จัก GRE รึยัง ด้วยคำสั่ง `sudo modprobe ip_gre` ถ้าไม่มีอะไรเด้งขึ้นมาก็แปลว่าโอเค
- สร้าง tunnel interface: ผมตั้งชื่อมันว่า gre1 ด้วยคำสั่ง `sudo ip tunnel add gre1 mode gre remote 2.2.2.2 local 1.1.1.1 ttl 255`
- `gre1` คือชื่อที่เราตั้ง
- `mode gre` ก็บอกว่าใช้โหมด GRE
- `remote 2.2.2.2` อันนี้คือ Public IP ของ Server B ที่เราจะเชื่อมไปหา
- `local 1.1.1.1` อันนี้คือ Public IP ของ Server A เอง
- `ttl 255` ก็ค่า Time-to-Live ปกติ
- ทำให้ interface มัน active: ใช้คำสั่ง `sudo ip link set gre1 up`
- ตั้ง IP Address ให้กับ tunnel: อันนี้สำคัญมากครับ เราต้องกำหนด IP Address ให้กับปลายท่อของเรา ผมเลือกใช้ IP ภายใน สมมติเป็น 10.0.1.1/24 ก็ใช้คำสั่ง `sudo ip addr add 10.0.1.1/24 dev gre1`
พอทำฝั่ง Server A เสร็จแล้ว หน้าตามันก็จะมี interface gre1 โผล่ขึ้นมา พร้อม IP 10.0.1.1
ฝั่ง Server B (สมมติ Public IP คือ 2.2.2.2)
ฝั่งนี้ก็ทำคล้ายๆ กันเลยครับ แต่สลับ IP remote กับ local กัน:
- เปิดใช้งาน module ip_gre: เหมือนเดิมครับ `sudo modprobe ip_gre`
- สร้าง tunnel interface: ผมก็ตั้งชื่อ gre1 เหมือนกัน `sudo ip tunnel add gre1 mode gre remote 1.1.1.1 local 2.2.2.2 ttl 255`
- สังเกตว่า `remote` เป็น 1.1.1.1 (IP Server A) และ `local` เป็น 2.2.2.2 (IP Server B)
- ทำให้ interface มัน active: `sudo ip link set gre1 up`
- ตั้ง IP Address ให้กับ tunnel: ผมให้ฝั่งนี้เป็น 10.0.1.2/24 `sudo ip addr add 10.0.1.2/24 dev gre1`
เท่านี้เองครับ สำหรับการตั้งค่าพื้นฐาน!
ลองทดสอบดูสิ!
พอตั้งค่าเสร็จทั้งสองฝั่ง ผมก็ลองเลยครับ จาก Server A ผมลอง ping ไปหา IP tunnel ของ Server B ก็คือ `ping 10.0.1.2` ปรากฏว่ามันตอบกลับมา! เยี่ยมไปเลย แปลว่าท่อ GRE ของเรามันเชื่อมกันได้แล้ว
ทีนี้ ถ้าอยากให้เครื่องอื่นๆ ในวง LAN ของ Server A คุยกับเครื่องในวง LAN ของ Server B ได้ ก็ต้องไปเพิ่ม static route หรือใช้พวก routing protocol อย่าง OSPF เข้ามาช่วยอีกทีนึง เพื่อให้มันรู้ว่าจะส่งข้อมูลข้ามท่อ GRE นี้ไปได้ยังไง อันนั้นก็จะเป็นอีกเรื่องนึงที่ต้องทำต่อครับ
อ้อ! อีกอย่างที่สำคัญเลยคือเรื่อง MTU (Maximum Transmission Unit) บางทีถ้าตั้งค่าไม่ดี ข้อมูลก้อนใหญ่ๆ มันจะส่งผ่าน tunnel ไม่ได้ อาจจะต้องปรับลดค่า MTU ของ interface gre1 ลงมาหน่อย เช่นเหลือสัก 1400 bytes ไรงี้ เพราะว่า GRE header มันก็กินพื้นที่ไปส่วนนึงแล้ว

สรุปง่ายๆ คือ GRE tunnel มันก็เป็นวิธีนึงที่ทำให้เครือข่ายสองที่มันคุยกันได้ผ่านอินเทอร์เน็ต เหมือนมีสาย LAN ส่วนตัวยาวๆ พาดผ่านไปเลย แต่ต้องจำไว้นิดนึงว่า GRE เพียวๆ เนี่ยมันไม่ได้เข้ารหัสข้อมูลนะ ถ้าอยากให้ปลอดภัยจริงๆ ควรจะใช้ร่วมกับพวก IPsec อีกทีนึง เพื่อให้ข้อมูลที่วิ่งในท่อมันถูกเข้ารหัสด้วย
นี่ก็เป็นประสบการณ์ที่ผมลองทำดูครับ ไม่ได้ยากอย่างที่คิดเลยใช่ไหมครับ ใครสนใจก็ลองไปเล่นกันดูได้นะครับ สนุกดีเหมือนกัน ได้เข้าใจหลักการทำงานของ network มากขึ้นด้วย!