WireGuard PersistentKeepalive: รักษาการแมป NAT ให้มีชีวิต
หากการเชื่อมต่อย้อนกลับทำงานเฉพาะทันทีหลังจากเพียร์ส่งทราฟฟิก การแมปกำลังหมดอายุ ตั้งค่า keepalive หลังเราเตอร์แล้วอ่าน timeout จริง
กล่องที่บ้านเปิดอุโมงค์และไปถึงเซิร์ฟเวอร์คลาวด์ได้โดยไม่มีปัญหา หลังจากกล่องที่บ้านส่งอะไรบางอย่างครั้งล่าสุด เซิร์ฟเวอร์คลาวด์เข้าถึงแอปพลิเคชันที่บ้านได้ประมาณหนึ่งหรือสองนาทีแล้วก็หยุด ไม่มีอะไรปรากฏในบันทึกของ WireGuard ไม่มีรายงานข้อผิดพลาดการจับมือ และการรีสตาร์ตอุโมงค์แก้ไขได้ชั่วคราว รูปแบบนี้คือการแมปที่หมดอายุ ไม่ใช่อุโมงค์ที่เสีย และคู่มือด้านล่างยืนยันเรื่องนี้ก่อนจะเปลี่ยนอะไร
ยืนยันว่ารูปแบบคือการหมดอายุเมื่อไม่มีกิจกรรม
รายละเอียดที่แยกแยะคือเวลา หากการเชื่อมต่อย้อนกลับทำงานทันทีหลังจากเพียร์ที่บ้านส่งทราฟฟิกและล้มเหลวหลังจากช่วงเวลาที่เงียบ แสดงว่าเส้นทางดีแต่สถานะตรงกลางไม่ดี หากไม่เคยทำงานเลยแม้แต่หลังส่งทราฟฟิก นี่คือการวินิจฉัยที่ผิด
sudo wg show wg0 latest-handshakes
sudo wg show wg0 endpoints
sudo wg show wg0 transfer
รันสองคำสั่งแรกทันทีหลังจากเพียร์ที่บ้านส่งอะไรบางอย่าง รอห้านาทีแล้วรันอีกครั้ง การประทับเวลาจับมือที่ต่ออายุตามกำหนดโดยไม่มีปลายทางใหม่บอกคุณว่าอุโมงค์ยังมีชีวิต สิ่งที่เปลี่ยนไปคือความสามารถของแพ็กเก็ตที่ไม่ได้รับคำขอให้มาถึงจากภายนอก ซึ่งเป็นคุณสมบัติของเส้นทางไม่ใช่อุโมงค์
จากนั้นลองย้อนกลับและดูตัวนับการถ่ายโอน หากฝั่งคลาวด์ส่งไบต์แต่ฝั่งบ้านไม่ได้รับเลย แพ็กเก็ตออกจากคลาวด์และตายในอุปกรณ์ที่เก็บสถานะระหว่างทาง นี่คือลายเซ็นที่คุณกำลังมองหา หากตัวนับทั้งสองเคลื่อนไหว อุโมงค์ส่งแพ็กเก็ตถึงแล้วและแอปพลิเคชันคือผู้ต้องสงสัย
วาง keepalive ไว้บนเพียร์ที่อยู่หลังเราเตอร์
keepalive แบบถาวรรักษาการแมป NAT และสถานะไฟร์วอลล์ใด ๆ ให้มีชีวิตด้วยการส่งแพ็กเก็ตขนาดเล็กที่ผ่านการรับรองตามกำหนดเวลา การตั้งค่านี้เป็นของเครื่องที่อยู่หลังเราเตอร์ ในรายการของเพียร์ระยะไกล เพราะฝั่งนั้นเป็นฝั่งที่แพ็กเก็ตขาออกสร้างสถานะ
[Peer]
PublicKey = <cloud peer public key>
AllowedIPs = 10.71.0.1/32
PersistentKeepalive = 25
รวมเข้ากับส่วนเพียร์ที่มีอยู่ การเพิ่มบล็อกที่สองด้วยคีย์สาธารณะเดียวกันไม่ใช่วิธีที่ถูกต้องในการเพิ่มตัวเลือก และ wg-quick จะไม่รวมให้คุณ 25 วินาทีที่ระบุในเอกสารเป็นตัวอย่างที่เลือกให้อยู่ต่ำกว่าค่า timeout UDP ทั่วไป ไม่ใช่ค่าที่มีความหมายพิเศษ
การวางคำสั่งเดียวกันไว้ฝั่งคลาวด์ไม่ช่วยแก้ปัญหานี้ แพ็กเก็ตของเพียร์นั้นมาจากที่อยู่สาธารณะอยู่แล้ว จึงไม่มีแมปให้รักษาในทิศทางที่สำคัญ มันเพิ่มทราฟฟิกและไม่เปลี่ยนอะไร
อ่านตัวจับเวลาแทนการเดาช่วงเวลา
keepalive ทำงานเพราะมาบ่อยกว่าที่สถานะจะหมดอายุ นั่นทำให้ timeout เป็นตัวเลขที่คุณต้องการจริง ๆ และบน Linux สามารถอ่านได้บนอุปกรณ์ที่ทำการแปล:
sysctl net.netfilter.nf_conntrack_udp_timeout
sysctl net.netfilter.nf_conntrack_udp_timeout_stream
sudo conntrack -L -p udp --dport 51820
ค่าแรกคือ timeout สำหรับโฟลว์ UDP ที่เห็นเพียงทิศทางเดียว และค่าที่สองใช้เมื่อสังเกตเห็นการตอบกลับแล้ว ทั้งสองมักสั้น และแมปที่เงียบลงจะทำตามค่าที่ใช้กับโฟลว์ของคุณ
เปรียบเทียบตัวเลขนั้นกับช่วงเวลาของคุณ keepalive 25 วินาทีภายใต้ timeout 30 วินาทีทำงานได้ keepalive เดียวกันภายใต้ timeout 15 วินาทีไม่ทำงาน การลองซ้ำไม่เปลี่ยนเลขคณิตนั้น เราเตอร์ผู้บริโภคและผู้ให้บริการมือถือบางรายใช้ค่าที่สั้นกว่าค่าเริ่มต้นของ Linux มาก นี่จึงเป็นเหตุผลที่การกำหนดค่าที่ทำงานบนเครือข่ายหนึ่งล้มเหลวบนอีกเครือข่าย
| Observation | What it means | Reasonable response |
|---|---|---|
| Works after traffic, dies when idle | Mapping or firewall state expiring | Lower the keepalive interval |
| Never works, even immediately | No return route, listener or firewall | Stop tuning keepalive |
| Works for hours, then dies once | Carrier-side translation or address change | Check the endpoint and logs together |
ตรวจสอบตัวรับฟังและไฟร์วอลล์แยกกัน
แมปที่มีชีวิตเป็นสิ่งจำเป็นแต่ไม่เพียงพอ แอปพลิเคชันบนกล่องที่บ้านต้องรับฟังที่อยู่ที่ถูกต้อง และไฟร์วอลล์ของโฮสต์ต้องอนุญาตแพ็กเก็ตหลังถอดรหัส
sudo ss -lntup | grep 8080
sudo wg show wg0 allowed-ips
curl -sS -m 5 http://10.71.0.2:8080/health
หากซ็อกเก็ตผูกกับที่อยู่ของอินเทอร์เฟซทางกายภาพเท่านั้น ไม่ใช่ที่อยู่ของอุโมงค์ แพ็กเก็ตที่มาบนอุโมงค์จะถูกทิ้งก่อนที่ไฟร์วอลล์จะถูกถามด้วยซ้ำ ความล้มเหลวนี้ดูจากฝั่งคลาวด์เหมือนปัญหาแมปทุกประการ และอยู่รอดจากการปรับ keepalive ทุกครั้ง
การตรวจสอบรายการที่อนุญาตก็สำคัญพอ ๆ กันในอีกทิศทาง เพียร์ฝั่งคลาวด์ต้องอนุญาตที่อยู่ของอุโมงค์ที่บ้านเป็นต้นทางหากจะตอบกลับ และเพียร์ฝั่งบ้านต้องอนุญาตที่อยู่คลาวด์เป็นปลายทาง แพ็กเก็ต keepalive เป็นทราฟฟิกที่ผ่านการรับรองและใช้กฎเดียวกัน นี่จึงเป็นเหตุผลที่ keepalive ที่ดูเหมือนทำงานสามารถอยู่ร่วมกับแอปพลิเคชันที่ไม่ทำงานได้
นำการเปลี่ยนแปลงไปใช้และรู้ขีดจำกัด
ใช้การตั้งค่า รีสตาร์ตอินเทอร์เฟซหากเป็นวิธีอัปเดตของคุณ แล้วทำการทดสอบเมื่อไม่มีกิจกรรมซ้ำแทนการทดสอบทันที รอให้นานกว่า timeout ที่คุณอ่านไว้ก่อนหน้านี้ ทำคำขอย้อนกลับ และยืนยันว่าตัวนับเคลื่อนไหวที่ทั้งสองปลาย
บันทึกช่วงเวลาและ timeout ที่วัดได้ไว้ข้าง ๆ การเปลี่ยนแปลงเฟิร์มแวร์ของเราเตอร์ในอนาคต หรือการย้ายไปใช้การเชื่อมต่อมือถือ อาจเปลี่ยน timeout ได้ บันทึกนี่เองที่ทำให้คนอื่นสามารถหาค่ากลับมาได้แทนการคัดลอก สองตัวเลขในบรรทัดเดียวประหยัดการสอบสวนทั้งครั้งในภายหลัง
keepalive แบบถาวรปกป้องสถานะ มันไม่เปิดพอร์ต ไม่เพิ่มรายการในรายการที่อนุญาต และไม่ทำให้ตัวรับฟังปรากฏขึ้น เมื่อการเชื่อมต่อย้อนกลับไม่ทำงานเลย ความผิดอยู่ที่หนึ่งในสามอย่างนั้น และ คู่มือเริ่มต้นอย่างรวดเร็วของ WireGuard อธิบายการตั้งค่า keepalive ด้วยถ้อยคำแคบ ๆ เดียวกัน