คู่มืออ้างอิง API สำหรับ WireGuard รวมถึงการตั้งค่า การกำหนดค่า และการใช้งาน พร้อมตัวอย่าง
เครดิตทั้งหมดไปที่โครงการ WireGuard, zx2c4 และผู้สนับสนุนโอเพ่นซอร์สสำหรับซอฟต์แวร์ต้นฉบับ
นี่เป็นความพยายามอย่างไม่เป็นทางการเดี่ยวของฉันในการจัดเตรียมเอกสารอ้างอิง API และตัวอย่างที่ครอบคลุมมากขึ้น
แหล่งที่มาของเอกสารเหล่านี้ โค้ดตัวอย่าง และตัวติดตามปัญหา: https://github.com/pirate/wireguard-docs เวอร์ชันหน้า HTML ที่ดีกว่า: https://docs.sweeting.me/s/wireguard
WireGuard เป็นโซลูชัน VPN แบบโอเพ่นซอร์สที่เขียนด้วยภาษา C โดย Jason Donenfeld และคนอื่นๆ โดยมีจุดมุ่งหมายเพื่อแก้ไขปัญหาต่างๆ มากมายที่รบกวนข้อเสนอ VPN แบบเซิร์ฟเวอร์ต่อเซิร์ฟเวอร์สมัยใหม่อื่นๆ เช่น IPSec/IKEv2, OpenVPN หรือ L2TP มันมีความคล้ายคลึงบางอย่างกับข้อเสนอ VPN สมัยใหม่อื่น ๆ เช่น Tinc และ MeshBird กล่าวคือ ชุดรหัสที่ดีและการกำหนดค่าขั้นต่ำ ในปี 2020-01 ได้มีการรวมเข้ากับเคอร์เนล Linux เวอร์ชัน 5.6 ซึ่งหมายความว่าจะจัดส่งพร้อมกับระบบ Linux ส่วนใหญ่ทันทีที่แกะกล่อง
ลิงค์อย่างเป็นทางการ
wg
, wg-quick
เป้าหมาย WireGuard
ดู https://github.com/pirate/wireguard-docs สำหรับโค้ดตัวอย่างและแหล่งเอกสารประกอบ
ไม่ว่าจะอาศัยอยู่หลังกำแพงเมืองจีนหรือเพียงพยายามสร้างเครือข่ายระหว่างเซิร์ฟเวอร์ของคุณ WireGuard เป็นตัวเลือกที่ยอดเยี่ยมและทำหน้าที่เป็น "บล็อกเลโก้" สำหรับการสร้างเครือข่าย (ในลักษณะเดียวกับที่ ZFS เป็นบล็อกเลโก้สำหรับสร้างระบบไฟล์ ).
สิ่งที่ WireGuard ไม่ได้ทำ:
แต่คุณสามารถเขียนวิธีแก้ปัญหาของคุณเองสำหรับปัญหาเหล่านี้ได้โดยใช้ WireGuard ภายใต้ประทุน (เช่น Tailscale หรือ AltheaNet)
สิ่งเหล่านี้คือชื่อโฮสต์สาธิต ชื่อโดเมน ที่อยู่ IP และช่วงที่ใช้ในเอกสารประกอบและการกำหนดค่าตัวอย่าง แทนที่ด้วยค่าที่คุณต้องการเมื่อทำการตั้งค่าของคุณเอง
example-vpn.dev
สามารถแทนที่ได้ด้วยโดเมนสาธารณะใดๆ ที่คุณควบคุมได้public-server1
, public-server2
, home-server
, laptop
, phone
สามารถเปลี่ยนเป็นชื่อโฮสต์ของอุปกรณ์ของคุณได้192.0.2.1/24
, 192.0.2.3
, 192.0.2.3/32
, 2001:DB8::/64
สามารถแทนที่ด้วยเครือข่ายย่อยและที่อยู่ที่คุณต้องการ (เช่น 192.168.5.1/24
)เมื่อใดก็ตามที่คุณเห็นสตริงเหล่านี้ด้านล่าง สตริงเหล่านี้จะถูกใช้เป็นค่าตัวยึดตำแหน่งเพื่อแสดงตัวอย่างและไม่มีความหมายพิเศษ
อย่าลืมเปลี่ยนที่อยู่ IP ในการกำหนดค่าของคุณ! บล็อกที่ใช้ในเอกสารเหล่านี้สงวนไว้สำหรับวัตถุประสงค์ตัวอย่างโดย IETF และไม่ควรนำไปใช้ในการตั้งค่าเครือข่ายจริง
192.0.2.0/24
(TEST-NET-1) ช่วงตัวอย่าง IPv4 RFC57372001:DB8::/32
ช่วงตัวอย่าง IPv6 RFC3849 คุณสามารถใช้ช่วงส่วนตัวใดๆ ที่คุณต้องการสำหรับการตั้งค่าของคุณเอง เช่น 10.0.44.0/24
เพียงตรวจสอบให้แน่ใจว่าไม่ขัดแย้งกับช่วงเครือข่ายย่อย LAN ใดๆ ที่เครื่องของคุณเปิดอยู่
โฮสต์ที่เชื่อมต่อกับ VPN และลงทะเบียนที่อยู่เครือข่ายย่อย VPN เช่น 192.0.2.3
สำหรับตัวมันเอง นอกจากนี้ยังสามารถเลือกกำหนดเส้นทางการรับส่งข้อมูลได้มากกว่าที่อยู่ของตัวเองโดยการระบุช่วงเครือข่ายย่อยในรูปแบบ CIDR ที่คั่นด้วยเครื่องหมายจุลภาค
เพียร์/โหนดที่เข้าถึงได้แบบสาธารณะซึ่งทำหน้าที่เป็นทางเลือกในการถ่ายทอดการรับส่งข้อมูลสำหรับเพียร์ VPN อื่น ๆ ที่อยู่เบื้องหลัง NAT เซิร์ฟเวอร์ตีกลับไม่ใช่เซิร์ฟเวอร์ประเภทพิเศษ มันเป็นเพียร์ปกติเหมือนกับเซิร์ฟเวอร์อื่นๆ ข้อแตกต่างเพียงอย่างเดียวคือมี IP สาธารณะและเปิดการส่งต่อ IP ระดับเคอร์เนลซึ่งช่วยให้สามารถตีกลับการรับส่งข้อมูลกลับลงมาที่ VPN ให้กับลูกค้ารายอื่น
ดูเพิ่มเติม: https://tailscale.com/blog/how-nat-traversal-works/ (Tailscale ใช้ Wireguard ใต้ฝากระโปรง)
กลุ่มของ IP ที่แยกจากอินเทอร์เน็ตสาธารณะ เช่น 192.0.2.1-255 หรือ 192.168.1.1/24 โดยทั่วไปจะอยู่เบื้องหลัง NAT ที่เราเตอร์จัดเตรียมไว้ให้ เช่น ใน LAN อินเทอร์เน็ตในสำนักงาน หรือเครือข่าย Wi-Fi ในบ้าน
วิธีการกำหนดซับเน็ตและขนาดด้วย "มาสก์" มาสก์ที่เล็กลง = บิตที่อยู่เพิ่มเติมที่ซับเน็ตใช้งานได้ & IP ที่มากขึ้นในช่วง สิ่งที่พบบ่อยที่สุด:
192.0.2.1/32
(ที่อยู่ IP เดียว 192.0.2.1
) netmask = 255.255.255.255
192.0.2.1/24
(255 IP ตั้งแต่ 192.0.2.0
- 192.0.2.255
) เน็ตมาสก์ = 255.255.255.0
192.0.2.1/16
(65,536 IP จาก 192.0.0.0
- 192.0.255.255
) เน็ตมาสก์ = 255.255.0.0
192.0.2.1/8
(16,777,216 IP จาก 192.0.0.0
- 192.255.255.255
) เน็ตมาสก์ = 255.0.0.0
0.0.0.1/0
(4,294,967,296 IP ตั้งแต่ 0.0.0.0
- 255.255.255.255
) เน็ตมาสก์ = 0.0.0.0
2001:DB8::/64
https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing
สำหรับผู้ที่เพิ่งเริ่มต้น 192.0.2.1/32
อาจดูเหมือนเป็นวิธีที่แปลกและน่าสับสนในการอ้างถึง IP เดียว การออกแบบนี้ดีเพราะช่วยให้เพื่อนเปิดเผย IP หลายรายการได้หากจำเป็นโดยไม่จำเป็นต้องใช้สัญลักษณ์หลายรายการ เพิ่งรู้ว่าทุกที่ที่คุณเห็นบางอย่างเช่น 192.0.2.3/32
มันหมายถึง 192.0.2.3
จริงๆ
ซับเน็ตที่มี IP ส่วนตัวที่เราเตอร์ยืนอยู่ด้านหน้าพวกเขาทำการแปลที่อยู่เครือข่าย แต่ละโหนดไม่สามารถเข้าถึงได้แบบสาธารณะจากอินเทอร์เน็ต แต่เราเตอร์จะติดตามการเชื่อมต่อขาออกและส่งต่อการตอบสนองไปยัง IP ภายในที่ถูกต้อง (เช่น เครือข่ายสำนักงานมาตรฐาน , เครือข่าย Wi-Fi ในบ้าน, เครือข่าย Wi-Fi สาธารณะฟรี ฯลฯ)
ที่อยู่ที่เข้าถึงได้สาธารณะ: พอร์ตสำหรับโหนด เช่น 123.124.125.126:1234
หรือ some.domain.tld:1234
(ต้องสามารถเข้าถึงได้ผ่านอินเทอร์เน็ตสาธารณะ โดยทั่วไปไม่สามารถเป็น IP ส่วนตัวเช่น 192.0.2.1
หรือ 192.168.1.1
เว้นแต่ สามารถเข้าถึงได้โดยตรงโดยใช้ที่อยู่นั้นโดยเพื่อนอื่น ๆ บนเครือข่ายย่อยเดียวกัน)
คีย์ส่วนตัว WireGuard สำหรับโหนดเดียว สร้างด้วย: wg genkey > example.key
(ไม่ต้องออกจากโหนดที่สร้างขึ้น)
คีย์สาธารณะ WireGuard สำหรับโหนดเดียว สร้างด้วย: wg pubkey < example.key > example.key.pub
(แชร์กับเพียร์อื่นๆ)
เซิร์ฟเวอร์ชื่อโดเมน ใช้เพื่อแก้ไขชื่อโฮสต์เป็น IP สำหรับไคลเอนต์ VPN แทนที่จะอนุญาตให้คำขอ DNS รั่วไหลภายนอก VPN และเปิดเผยการรับส่งข้อมูล การรั่วไหลสามารถทดสอบได้ด้วย http://dnsleak.com
การถ่ายทอดสาธารณะเป็นเพียงเพียร์ VPN ปกติที่สามารถทำหน้าที่เป็นเซิร์ฟเวอร์การถ่ายทอดระดับกลางระหว่างไคลเอนต์ VPN ใด ๆ ที่อยู่เบื้องหลัง NAT พวกเขาสามารถส่งต่อการรับส่งข้อมูลเครือข่ายย่อย VPN ใด ๆ ที่พวกเขาได้รับไปยังเพียร์ที่ถูกต้องในระดับระบบ (WireGuard ไม่สนใจว่าสิ่งนี้จะเกิดขึ้นได้อย่างไร มันถูกจัดการโดยเคอร์เนล net.ipv4.ip_forward = 1
และกฎการกำหนดเส้นทาง iptables)
หากเพื่อนทั้งหมดสามารถเข้าถึงได้แบบสาธารณะ คุณไม่จำเป็นต้องกังวลเกี่ยวกับการดูแลเป็นพิเศษในการทำให้หนึ่งในนั้นเป็นเซิร์ฟเวอร์รีเลย์ ซึ่งจำเป็นก็ต่อเมื่อคุณมีเพื่อนที่เชื่อมต่อจากด้านหลัง NAT
ไคลเอนต์แต่ละรายจำเป็นต้องกำหนดเซิร์ฟเวอร์/เพียร์ที่เข้าถึงได้แบบสาธารณะในการกำหนดค่าเท่านั้น การรับส่งข้อมูลใด ๆ ที่เชื่อมโยงกับเพียร์อื่น ๆ ที่อยู่เบื้องหลัง NAT จะไปที่ซับเน็ต VPN ที่รับทั้งหมด (เช่น 192.0.2.1/24
) ในเส้นทาง AllowedIPs
รีเลย์สาธารณะ และจะถูกส่งต่อตามนั้น เมื่อมันกระทบเซิร์ฟเวอร์รีเลย์
โดยสรุป: ควรกำหนดค่าเฉพาะการเชื่อมต่อโดยตรงระหว่างไคลเอนต์เท่านั้น การเชื่อมต่อใดๆ ที่ต้องเด้งกลับไม่ควรถูกกำหนดให้เป็นเพียร์ เนื่องจากควรไปที่เซิร์ฟเวอร์ตีกลับก่อน และถูกกำหนดเส้นทางจากที่นั่นกลับลง VPN ไปยังไคลเอนต์ที่ถูกต้อง
โทโพโลยีที่ซับซ้อนมากขึ้นสามารถทำได้อย่างแน่นอน แต่นี่เป็นวิธีการกำหนดเส้นทางพื้นฐานที่ใช้ในการตั้งค่า WireGuard ทั่วไป:
Endpoint
เพื่อให้ WireGuard สามารถเชื่อมต่อโดยตรงกับพอร์ตที่เปิดอยู่และกำหนดเส้นทางแพ็กเก็ต UDP โดยไม่ต้องกระโดดข้ามระดับกลางpublic-server2
) ให้กำหนดโหนดที่เข้าถึงได้แบบสาธารณะด้วย Endpoint
แบบฮาร์ดโค้ดและโหนด NAT-ed ที่ไม่มี การเชื่อมต่อจะถูกเปิดจากไคลเอนต์ NAT -> ไคลเอนต์สาธารณะ จากนั้นการรับส่งข้อมูลจะกำหนดเส้นทางโดยตรงระหว่างพวกเขาในทั้งสองทิศทางตราบใดที่การเชื่อมต่อยังคงอยู่โดยส่ง Ping PersistentKeepalive
ขาออกจากไคลเอนต์ NAT-edpublic-server1
และการรับส่งข้อมูลจะส่งต่อผ่านเซิร์ฟเวอร์ตีกลับตัวกลางตราบใดที่การเชื่อมต่อ จะถูกเก็บไว้มีชีวิตอยู่ เส้นทางที่เฉพาะเจาะจงมากขึ้น (และมักจะตรงกว่า) ที่เพื่อนคนอื่น ๆ มอบให้จะมีความสำคัญเหนือกว่าเมื่อมีให้บริการ มิฉะนั้นการรับส่งข้อมูลจะถอยกลับไปยังเส้นทางที่เฉพาะเจาะจงน้อยที่สุด และใช้ 192.0.2.1/24
catchall เพื่อส่งต่อการรับส่งข้อมูลไปยังเซิร์ฟเวอร์ตีกลับ ซึ่งเส้นทางนั้นจะอยู่ในนั้น เลี้ยวถูกกำหนดเส้นทางโดยตารางเส้นทางระบบของเซิร์ฟเวอร์รีเลย์ ( net.ipv4.ip_forward = 1
) สำรอง VPN ไปยังเพียร์เฉพาะที่ยอมรับเส้นทางสำหรับการรับส่งข้อมูลนั้น WireGuard จะไม่ค้นหาเส้นทางที่เร็วที่สุดโดยอัตโนมัติหรือพยายามสร้างการเชื่อมต่อโดยตรงระหว่างเพียร์ หากยังไม่ได้กำหนดไว้ เพียงแต่เปลี่ยนจากเส้นทางที่เฉพาะเจาะจงที่สุดใน [Peers]
ไปสู่เส้นทางที่เจาะจงน้อยที่สุด
คุณสามารถทราบได้ว่า WireGuard ใช้วิธีการกำหนดเส้นทางแบบใดสำหรับที่อยู่ที่ระบุ โดยการวัดเวลา ping เพื่อหาความยาวเฉพาะของแต่ละฮอป และโดยการตรวจสอบผลลัพธ์ของ:
wg show wg0
WireGuard ใช้แพ็กเก็ต UDP ที่เข้ารหัสสำหรับการรับส่งข้อมูลทั้งหมด แต่ไม่ได้ให้การรับประกันเกี่ยวกับการจัดส่งหรือการสั่งซื้อแพ็กเก็ต เนื่องจากได้รับการจัดการโดยการเชื่อมต่อ TCP ภายในอุโมงค์ที่เข้ารหัส
อ่านเพิ่มเติม:
WireGuard อ้างว่ามีประสิทธิภาพเร็วกว่าโซลูชัน VPN คู่แข่งอื่นๆ ส่วนใหญ่ แม้ว่าบางครั้งจะมีการถกเถียงถึงตัวเลขที่แน่นอนและอาจขึ้นอยู่กับว่าการเร่งความเร็วระดับฮาร์ดแวร์นั้นใช้ได้กับรหัสเข้ารหัสบางตัวหรือไม่
ประสิทธิภาพของ WireGuard เกิดขึ้นได้จากการจัดการเส้นทางในระดับเคอร์เนล และโดยการใช้ชุดการเข้ารหัสที่ทันสมัยที่ทำงานบนคอร์ทั้งหมดเพื่อเข้ารหัสการรับส่งข้อมูล WireGuard ยังได้รับข้อได้เปรียบที่สำคัญจากการใช้ UDP โดยไม่มีการรับประกันการจัดส่ง/การสั่งซื้อ (เปรียบเทียบกับ VPN ที่ทำงานผ่าน TCP หรือใช้กลไกการจัดส่งที่รับประกันของตนเอง)
อ่านเพิ่มเติม:
WireGuard ใช้โปรโตคอลและพื้นฐานต่อไปนี้เพื่อรักษาความปลอดภัยการรับส่งข้อมูล:
การเข้ารหัสของ WireGuard นั้นเป็นการสร้างอินสแตนซ์ของเฟรมเวิร์ก Noise ของ Trevor Perrin โดยพื้นฐานแล้ว มันทันสมัยและเรียบง่ายอีกครั้ง ตัวเลือก VPN อื่นๆ ทั้งหมดนั้นยุ่งยากในการเจรจาและการจับมือกันและกลไกสถานะที่ซับซ้อน WireGuard เปรียบเสมือน Signal/Axolotl ของ VPN ยกเว้นว่าง่ายกว่าและง่ายกว่ามากในการให้เหตุผล (ในกรณีนี้คือการเข้ารหัส) มากกว่าโปรโตคอลการส่งข้อความวงล้อคู่ โดยพื้นฐานแล้วมันคือ qmail ของซอฟต์แวร์ VPN และมีโค้ดประมาณ 4,000 บรรทัด มันเป็นคำสั่งที่มีขนาดพหูพจน์น้อยกว่าคู่แข่ง
https://news.ycombinator.com/item?id=14599834
อ่านเพิ่มเติม:
การรับรองความถูกต้องในทั้งสองทิศทางทำได้โดยใช้คู่คีย์สาธารณะ/ส่วนตัวอย่างง่ายสำหรับแต่ละเพียร์ เพียร์แต่ละคนจะสร้างคีย์เหล่านี้ในระหว่างขั้นตอนการตั้งค่า และแบ่งปันเฉพาะคีย์สาธารณะกับเพียร์อื่น ๆ
ไม่จำเป็นต้องมีใบรับรองอื่นหรือคีย์ที่แชร์ล่วงหน้านอกเหนือจากคีย์สาธารณะ/ส่วนตัวสำหรับแต่ละโหนด
การสร้าง การแจกจ่าย และการเพิกถอนคีย์สามารถจัดการได้ในการปรับใช้ขนาดใหญ่โดยใช้บริการแยกต่างหาก เช่น Ansible หรือ Kubernetes Secrets
บริการบางอย่างที่ช่วยกระจายและปรับใช้คีย์:
คุณยังสามารถอ่านคีย์จากไฟล์หรือผ่านคำสั่งได้ หากคุณไม่ต้องการฮาร์ดโค้ดใน wg0.conf
ซึ่งจะทำให้การจัดการคีย์ผ่านบริการของบุคคลที่สามง่ายขึ้นมาก:
[Interface]
...
PostUp = wg set %i private-key /etc/wireguard/wg0.key <(cat /some/path/%i/privkey)
ในทางเทคนิคแล้ว เซิร์ฟเวอร์หลายเครื่องสามารถแชร์คีย์ส่วนตัวเดียวกันได้ ตราบใดที่ไคลเอนต์ไม่ได้เชื่อมต่อกับเซิร์ฟเวอร์สองเครื่องด้วยคีย์เดียวกันพร้อมกัน ตัวอย่างของสถานการณ์ที่เป็นการตั้งค่าที่สมเหตุสมผลคือ ถ้าคุณใช้ DNS แบบวนรอบเพื่อปรับสมดุลการโหลดระหว่างเซิร์ฟเวอร์สองเครื่องที่แกล้งทำเป็นเซิร์ฟเวอร์เดียว อย่างไรก็ตาม โดยส่วนใหญ่แล้ว เพียร์ทุกรายควรมีคู่คีย์สาธารณะ/ส่วนตัวของตัวเอง เพื่อให้เพียร์ไม่สามารถอ่านการรับส่งข้อมูลของกันและกัน และสามารถเพิกถอนทีละรายการได้
ภาพรวมของกระบวนการทั่วไป:
apt install wireguard
หรือ pkg/brew install wireguard-tools
บนแต่ละโหนดwg genkey
+ wg pubkey
wg0.conf
WireGuard บนเซิร์ฟเวอร์รีเลย์หลัก[Interface]
ตรวจสอบให้แน่ใจว่าได้ระบุช่วง CIDR สำหรับเครือข่ายย่อย VPN ทั้งหมดเมื่อกำหนดที่อยู่ที่เซิร์ฟเวอร์ยอมรับเส้นทางสำหรับ Address = 192.0.2.1/24
[Peer]
สร้างส่วนเพียร์สำหรับลูกค้าทุกคนที่เข้าร่วม VPN โดยใช้กุญแจสาธารณะระยะไกลที่เกี่ยวข้องwg0.conf
บนแต่ละโหนดไคลเอ็นต์[Interface]
ตรวจสอบให้แน่ใจว่าได้ระบุเพียง IP เดียวสำหรับไคลเอ็นต์เพียร์ที่ไม่ถ่ายทอดการรับส่งข้อมูล Address = 192.0.2.3/32
[Peer]
สร้างส่วนเพียร์สำหรับเพียร์สาธารณะแต่ละเพียร์ที่ไม่อยู่หลัง NAT ตรวจสอบให้แน่ใจว่าได้ระบุช่วง CIDR สำหรับซับเน็ต VPN ทั้งหมด เมื่อกำหนดเพียร์ระยะไกลที่ทำหน้าที่เป็นเซิร์ฟเวอร์ตีกลับ AllowedIPs = 192.0.2.1/24
ตรวจสอบให้แน่ใจว่าได้ระบุ IP แต่ละรายการสำหรับเพียร์ระยะไกลที่ไม่ส่งต่อการรับส่งข้อมูลและทำหน้าที่เป็นไคลเอ็นต์ธรรมดาเท่านั้น AllowedIPs = 192.0.2.3/32
wg-quick up /full/path/to/wg0.conf
wg-quick up /full/path/to/wg0.conf
ping 192.0.2.3
จะตรวจสอบเส้นทางตรงไปยังเพียร์ด้วย AllowedIPs = 192.0.2.3/32
ก่อน จากนั้นจึงถอยกลับไปยังเซิร์ฟเวอร์รีเลย์ที่ยอมรับ IP ในซับเน็ตทั้งหมด # install on Ubuntu
sudo add-apt-repository ppa:wireguard/wireguard
apt install wireguard
# install on macOS
brew install wireguard-tools
# install on FreeBSD
pkg install wireguard
# install on iOS/Android using Apple App Store/Google Play Store
# install on other systems using https://www.wireguard.com/install/#installation
# to enable the kernel relaying/forwarding ability on bounce servers
echo " net.ipv4.ip_forward = 1 " | sudo tee -a /etc/sysctl.conf
echo " net.ipv4.conf.all.proxy_arp = 1 " | sudo tee -a /etc/sysctl.conf
sudo sysctl -p /etc/sysctl.conf
# to add iptables forwarding rules on bounce servers
sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i wg0 -o wg0 -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -t nat -A POSTROUTING -s 192.0.2.0/24 -o eth0 -j MASQUERADE
nano wg0.conf # can be placed anywhere, must be referred to using absolute path (usually placed in /etc/wireguard/wg0.conf on most Linux systems)
# generate private key
wg genkey > example.key
# generate public key
wg pubkey < example.key > example.key.pub
wg-quick up /full/path/to/wg0.conf
wg-quick down /full/path/to/wg0.conf
# Note: you must specify the absolute path to wg0.conf, relative paths won't work
# If wg0.conf is in /etc/wireguard you can use the simpler:
wg-quick up wg0
# start/stop VPN network interface
ip link set wg0 up
ip link set wg0 down
# register/unregister VPN network interface
ip link add dev wg0 type wireguard
ip link delete dev wg0
# register/unregister local VPN address
ip address add dev wg0 192.0.2.3/32
ip address delete dev wg0 192.0.2.3/32
# register/unregister VPN route
ip route add 192.0.2.3/32 dev wg0
ip route delete 192.0.2.3/32 dev wg0
# show system LAN and WAN network interfaces
ip address show
# or if ip is not available:
ifconfig
# show system VPN network interfaces
ip link show wg0
# or
ifconfig wg0
# show WireGuard VPN interfaces
wg show all
wg show wg0
# show public IP address
ip address show eth0
# or
ifconfig eth0
# or
dig -4 +short myip.opendns.com @resolver1.opendns.com
# show VPN IP address
ip address show wg0
# show WireGuard routing table and peer connections
wg show
wg show wg0 allowed-ips
# show system routing table
ip route show table main
ip route show table local
# show system route to specific address
ip route get 192.0.2.3
หากต้องการเปิดใช้งานการบันทึกเพิ่มเติม:
modprobe wireguard
echo module wireguard +p > /sys/kernel/debug/dynamic_debug/control
หากต้องการติดตามบันทึก:
dmesg -wH
ระบบที่มีเคอร์เนลสมัยใหม่และ Safe Boot อาจจำเป็นต้องปิดการใช้งาน Secure Boot DKMS Signature Verification เพื่ออนุญาตการเข้าถึงบันทึกเคอร์เนล
mokutil --disable-verification
reboot
# check that the main relay server is accessible directly via public internet
ping public-server1.example-vpn.dev
# check that the main relay server is available via VPN
ping 192.0.2.1
# check that public peers are available via VPN
ping 192.0.2.2
# check that remote NAT-ed peers are available via VPN
ping 192.0.2.3
# check that NAT-ed peers in your local LAN are available via VPN
ping 192.0.2.4
# install iperf using your preferred package manager
apt/brew/pkg/opkg install iperf
# check bandwidth over public internet to relay server
iperf -s # on public relay server
iperf -c public-server1.example-vpn.dev # on local client
# check bandwidth over VPN to relay server
iperf -s # on public relay server
iperf -c 192.0.2.1 # on local client
# check bandwidth over VPN to remote public peer
iperf -s # on remote public peer
iperf -c 192.0.2.2 # on local client
# check bandwidth over VPN to remote NAT-ed peer
iperf -s # on remote NAT-ed peer
iperf -c 192.0.2.3 # on local client
# check bandwidth over VPN to local NAT-ed peer (on same LAN)
iperf -s # on local NAT-ed peer
iperf -c 192.0.2.4 # on local client
ตรวจสอบการรั่วไหลของ DNS โดยใช้ http://dnsleak.com หรือโดยการตรวจสอบตัวแก้ไขในการค้นหา:
dig example.com A
การกำหนดค่า WireGuard อยู่ในรูปแบบ INI ซึ่งกำหนดไว้ในไฟล์ที่มักเรียกว่า wg0.conf
สามารถวางไว้ที่ใดก็ได้ในระบบ แต่มักจะวางไว้ใน /etc/wireguard/wg0.conf
เส้นทางการกำหนดค่าถูกระบุเป็นอาร์กิวเมนต์เมื่อรันคำสั่ง wg-quick
ใด ๆ เช่น:
wg-quick up /etc/wireguard/wg0.conf
(ระบุเส้นทางแบบเต็มและแน่นอนเสมอ)
ชื่อไฟล์กำหนดค่าต้องอยู่ในรูปแบบ ${name of the new WireGuard interface}.conf
โดยทั่วไปชื่ออินเทอร์เฟซ WireGuard จะนำหน้าด้วย wg
และตัวเลขเริ่มต้นที่ 0
แต่คุณสามารถใช้ชื่อใดก็ได้ที่ตรงกับ regex ^[a-zA-Z0-9_=+.-]{1,15}$
ไฟล์กำหนดค่าสามารถเลือกใช้ชุดตัวเลือกการกำหนดค่า wg
ที่จำกัด หรือตัวเลือก wg-quick
ที่ขยายเพิ่มเติมได้ ขึ้นอยู่กับคำสั่งที่ต้องการเริ่ม WireGuard เอกสารเหล่านี้แนะนำให้ใช้ wg-quick
เพราะมันมอบประสบการณ์การกำหนดค่าที่ทรงพลังและใช้งานง่ายยิ่งขึ้น
ข้ามไปที่คำจำกัดความ:
¶ [Interface]
¶ # Name = node1.example.tld
¶ Address = 192.0.2.3/32
¶ ListenPort = 51820
¶ PrivateKey = localPrivateKeyAbcAbcAbc=
¶ DNS = 1.1.1.1,8.8.8.8
¶ Table = 12345
¶ MTU = 1500
¶ PreUp = /bin/example arg1 arg2 %i
¶ PostUp = /bin/example arg1 arg2 %i
¶ PreDown = /bin/example arg1 arg2 %i
¶ PostDown = /bin/example arg1 arg2 %i
¶ [Peer]
¶ # Name = node2-node.example.tld
¶ AllowedIPs = 192.0.2.1/24
¶ Endpoint = node1.example.tld:51820
¶ PublicKey = remotePublicKeyAbcAbcAbc=
¶ PersistentKeepalive = 25
[Interface]
กำหนดการตั้งค่า VPN สำหรับโหนดในเครื่อง
ตัวอย่าง
[Interface]
# Name = phone.example-vpn.dev
Address = 192.0.2.5/32
PrivateKey = <private key for phone.example-vpn.dev>
[Interface]
# Name = public-server1.example-vpn.tld
Address = 192.0.2.1/24
ListenPort = 51820
PrivateKey = <private key for public-server1.example-vpn.tld>
DNS = 1.1.1.1
# Name
นี่เป็นเพียงความคิดเห็นมาตรฐานในรูปแบบ INI ที่ใช้เพื่อช่วยติดตามว่าส่วนการกำหนดค่าใดเป็นของโหนดใด WireGuard จะละเว้นโดยสิ้นเชิง และไม่มีผลกระทบต่อพฤติกรรมของ VPN
หมายเหตุ: ความคิดเห็นทั้งหมด รวมถึง # Name
จะถูกลบออกจากไฟล์ .conf โดยการดำเนินการและแอปพลิเคชันบางอย่าง หากคุณต้องการระบุเพียร์ ให้พิจารณาใช้ตัวสร้างคีย์ vanity ของ wireguard เช่น wireguard-vanity-keygen หรือ wireguard-vanity-address ซึ่งจะช่วยให้คุณสามารถรวมชื่อโฮสต์ในคีย์สาธารณะของโฮสต์ได้ การสร้างคีย์อาจใช้เวลาเป็นนาที (4 ตัวอักษร) ชั่วโมง (5 ตัวอักษร) หรือนานกว่านั้น ดังนั้นให้พิจารณาใช้ตัวย่อสำหรับโฮสต์ที่มีชื่อยาวกว่า
Address
กำหนดช่วงที่อยู่ซึ่งโหนดในเครื่องควรกำหนดเส้นทางการรับส่งข้อมูล ขึ้นอยู่กับว่าโหนดนั้นเป็นไคลเอนต์ธรรมดาที่เข้าร่วมเครือข่ายย่อย VPN หรือเซิร์ฟเวอร์ตีกลับที่ถ่ายทอดการรับส่งข้อมูลระหว่างไคลเอนต์หลายตัว สามารถตั้งค่านี้เป็น IP เดียวของโหนดนั้นเอง (ระบุด้วยสัญลักษณ์ CIDR) เช่น 192.0.2.3/32 ) หรือช่วงของซับเน็ต IPv4/IPv6 ที่โหนดสามารถกำหนดเส้นทางการรับส่งข้อมูลได้
ตัวอย่าง
โหนดเป็นไคลเอ็นต์ที่กำหนดเส้นทางการรับส่งข้อมูลสำหรับตัวมันเองเท่านั้น
Address = 192.0.2.3/32
โหนดเป็นเซิร์ฟเวอร์ตีกลับสาธารณะที่สามารถถ่ายทอดการรับส่งข้อมูลไปยังเพียร์อื่นๆ
เมื่อโหนดทำหน้าที่เป็นเซิร์ฟเวอร์ตีกลับสาธารณะ โหนดควรตั้งค่านี้เป็นเครือข่ายย่อยทั้งหมดที่สามารถกำหนดเส้นทางการรับส่งข้อมูลได้ ไม่ใช่แค่ IP เดียวสำหรับตัวมันเอง
Address = 192.0.2.1/24
Address = 192.0.2.1/24,2001:DB8::/64
ListenPort
เมื่อโหนดทำหน้าที่เป็นเซิร์ฟเวอร์ตีกลับสาธารณะ โหนดควรฮาร์ดโค้ดพอร์ตเพื่อรับฟังการเชื่อมต่อ VPN ขาเข้าจากอินเทอร์เน็ตสาธารณะ ไคลเอนต์ที่ไม่ทำหน้าที่เป็นรีเลย์ไม่ควรตั้งค่านี้
ตัวอย่าง
ListenPort = 51820
ListenPort = 7000
PrivateKey
นี่คือคีย์ส่วนตัวสำหรับโหนดในเครื่อง ซึ่งไม่เคยแชร์กับเซิร์ฟเวอร์อื่น โหนดทั้งหมดต้องมีชุดคีย์ส่วนตัว ไม่ว่าจะเป็นเซิร์ฟเวอร์ตีกลับสาธารณะที่ถ่ายทอดการรับส่งข้อมูล หรือไคลเอนต์ธรรมดาที่เข้าร่วม VPN
คีย์นี้สามารถสร้างขึ้นได้ด้วย wg genkey > example.key
ตัวอย่าง
PrivateKey = somePrivateKeyAbcdAbcdAbcdAbcd=
DNS
เซิร์ฟเวอร์ DNS ที่จะประกาศไปยังไคลเอนต์ VPN ผ่าน DHCP ไคลเอนต์ส่วนใหญ่จะใช้เซิร์ฟเวอร์นี้สำหรับคำขอ DNS ผ่าน VPN แต่ไคลเอนต์ยังสามารถแทนที่ค่านี้ในเครื่องบนโหนดของพวกเขาได้
ตัวอย่าง
DNS = 1.1.1.1
DNS = 1.1.1.1,8.8.8.8
Table
เลือกกำหนดตารางเส้นทางที่จะใช้สำหรับเส้นทาง WireGuard โดยไม่จำเป็นต้องกำหนดค่าสำหรับการตั้งค่าส่วนใหญ่
มีค่าพิเศษสองค่า: 'ปิด' ปิดใช้งานการสร้างเส้นทางทั้งหมด และ 'อัตโนมัติ' (ค่าเริ่มต้น) จะเพิ่มเส้นทางลงในตารางเริ่มต้น และเปิดใช้งานการจัดการพิเศษของเส้นทางเริ่มต้น
https://git.zx2c4.com/WireGuard/about/src/tools/man/wg-quick.8
ตัวอย่าง
Table = 1234
MTU
กำหนดหน่วยการส่งข้อมูลสูงสุด (MTU หรือที่เรียกว่าขนาดแพ็กเก็ต/เฟรม) เพื่อใช้เมื่อเชื่อมต่อกับเพียร์ โดยไม่จำเป็นต้องกำหนดค่าสำหรับการตั้งค่าส่วนใหญ่
MTU จะถูกกำหนดโดยอัตโนมัติจากที่อยู่ปลายทางหรือเส้นทางเริ่มต้นของระบบ ซึ่งโดยปกติจะเป็นทางเลือกที่สมเหตุสมผล
https://git.zx2c4.com/WireGuard/about/src/tools/man/wg-quick.8
ตัวอย่าง
MTU = 1500
PreUp
รันคำสั่งก่อนที่จะแสดงอินเทอร์เฟซขึ้นมา ตัวเลือกนี้สามารถระบุได้หลายครั้ง โดยมีคำสั่งดำเนินการตามลำดับที่ปรากฏในไฟล์
ตัวอย่าง
PreUp = ip rule add ipproto tcp dport 22 table 1234
PostUp
ทางเลือกในการรันคำสั่งหลังจากอินเทอร์เฟซถูกแสดงขึ้นมา ตัวเลือกนี้สามารถปรากฏได้หลายครั้ง เช่นเดียวกับ PreUp
ตัวอย่าง
อ่านค่ากำหนดจากไฟล์หรือเอาต์พุตของคำสั่งบางคำสั่ง
PostUp = wg set %i private-key /etc/wireguard/wg0.key <(some command here)
บันทึกบรรทัดลงในไฟล์
PostUp = echo "$(date +%s) WireGuard Started" >> /var/log/wireguard.log
เข้าสู่เว็บฮุคบนเซิร์ฟเวอร์อื่น
PostUp = curl https://events.example.dev/wireguard/started/?key=abcdefg
เพิ่มเส้นทางไปยังตารางเส้นทางของระบบ
PostUp = ip rule add ipproto tcp dport 22 table 1234
เพิ่มกฎ iptables เพื่อเปิดใช้งานการส่งต่อแพ็คเก็ตบนอินเทอร์เฟซ WireGuard
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
บังคับให้ WireGuard แก้ไขที่อยู่ IP สำหรับโดเมนเพียร์อีกครั้ง
PostUp = resolvectl domain %i "~."; resolvectl dns %i 192.0.2.1; resolvectl dnssec %i yes
PreDown
รันคำสั่งก่อนที่อินเทอร์เฟซจะถูกปิด ตัวเลือกนี้สามารถปรากฏได้หลายครั้ง เช่นเดียวกับ PreUp
ตัวอย่าง
บันทึกบรรทัดลงในไฟล์
PostDown = echo "$(date +%s) WireGuard Going Down" >> /var/log/wireguard.log
เข้าสู่เว็บฮุคบนเซิร์ฟเวอร์อื่น
PostDown = curl https://events.example.dev/wireguard/stopping/?key=abcdefg
PostDown
ทางเลือกในการรันคำสั่งหลังจากที่อินเทอร์เฟซถูกปิดลง ตัวเลือกนี้สามารถปรากฏได้หลายครั้ง เช่นเดียวกับ PreUp
ตัวอย่าง
บันทึกบรรทัดลงในไฟล์
PostDown = echo "$(date +%s) WireGuard Stopped" >> /var/log/wireguard.log
เข้าสู่เว็บฮุคบนเซิร์ฟเวอร์อื่น
PostDown = curl https://events.example.dev/wireguard/stopped/?key=abcdefg
ลบกฎ iptables ที่ส่งต่อแพ็กเก็ตบนอินเทอร์เฟซ WireGuard
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
กำหนดการตั้งค่า VPN สำหรับเครื่องระยะไกลที่สามารถกำหนดเส้นทางการรับส่งข้อมูลสำหรับที่อยู่ตั้งแต่หนึ่งรายการขึ้นไป (ตัวมันเองและ/หรือเพียร์อื่น) เพียร์อาจเป็นเซิร์ฟเวอร์ตีกลับสาธารณะที่ถ่ายทอดการรับส่งข้อมูลไปยังเพียร์อื่นๆ หรือไคลเอ็นต์ที่เข้าถึงได้โดยตรงผ่าน LAN/อินเทอร์เน็ตที่ไม่ได้อยู่เบื้องหลัง NAT และกำหนดเส้นทางการรับส่งข้อมูลสำหรับตัวมันเองเท่านั้น
ไคลเอนต์ทั้งหมดจะต้องถูกกำหนดให้เป็นเพียร์บนเซิร์ฟเวอร์ตีกลับสาธารณะ ไคลเอนต์ธรรมดาที่กำหนดเส้นทางการรับส่งข้อมูลสำหรับตัวเองเท่านั้น จำเป็นต้องกำหนดเพียร์สำหรับการถ่ายทอดสาธารณะ และโหนดอื่น ๆ ที่สามารถเข้าถึงได้โดยตรง ไม่ ควรกำหนดโหนดที่อยู่หลัง NAT ที่แยกจากกันเป็นเพียร์นอกการกำหนดค่าเซิร์ฟเวอร์สาธารณะ เนื่องจากไม่มีเส้นทางตรงระหว่าง NAT ที่แยกจากกัน โหนดที่อยู่ด้านหลัง NAT ควรกำหนดเซิร์ฟเวอร์รีเลย์สาธารณะและไคลเอ็นต์สาธารณะอื่นๆ เป็นเพียร์เท่านั้น และควรระบุ AllowedIPs = 192.0.2.1/24
บนเซิร์ฟเวอร์สาธารณะที่ยอมรับเส้นทางและตีกลับการรับส่งข้อมูลสำหรับเครือข่ายย่อย VPN ไปยัง NAT-ed ระยะไกล เพื่อนร่วมงาน
โดยสรุป โหนดทั้งหมดจะต้องถูกกำหนดบนเซิร์ฟเวอร์ตีกลับหลัก บนเซิร์ฟเวอร์ไคลเอ็นต์ เฉพาะเพียร์ที่สามารถเข้าถึงได้โดยตรงจากโหนดเท่านั้นที่ควรกำหนดเป็นเพียร์ของโหนดนั้น เพียร์ใดๆ ที่ต้องส่งต่อโดยเซิร์ฟเวอร์ตีกลับควรละไว้ และจะได้รับการจัดการโดยเส้นทางที่รับทั้งหมดของเซิร์ฟเวอร์รีเลย์
ในการกำหนดค่าที่ระบุไว้ในเอกสารด้านล่าง เซิร์ฟเวอร์เดียว public-server1
ทำหน้าที่เป็นเซิร์ฟเวอร์รีเลย์ตีกลับสำหรับการผสมผสานระหว่างไคลเอนต์ที่เข้าถึงได้แบบสาธารณะและไคลเอนต์ NAT-ed และเพียร์ได้รับการกำหนดค่าในแต่ละโหนดตามลำดับ:
ใน public-server1
wg0.conf
(เซิร์ฟเวอร์ตีกลับ)
รายการ [peer]
: public-server2
, home-server
, laptop
, phone
ใน public-server2
wg0.conf
(ไคลเอ็นต์สาธารณะแบบธรรมดา)
รายการ [peer]
: public-server1
ใน home-server
wg0.conf
(ไคลเอนต์อย่างง่ายหลัง NAT)
รายการ [peer]
: public-server1
, public-server2
ใน laptop
wg0.conf
(ไคลเอนต์ธรรมดาที่อยู่เบื้องหลัง NAT)
รายการ [peer]
: public-server1
, public-server2
ใน phone
wg0.conf
(ไคลเอนต์ธรรมดาที่อยู่เบื้องหลัง NAT)
รายการ [peer]
: public-server1
, public-server2
ตัวอย่าง
[Peer]
# Name = public-server2.example-vpn.dev
Endpoint = public-server2.example-vpn.dev:51820
PublicKey = <public key for public-server2.example-vpn.dev>
AllowedIPs = 192.0.2.2/32
[Peer]
# Name = home-server.example-vpn.dev
Endpoint = home-server.example-vpn.dev:51820
PublicKey = <public key for home-server.example-vpn.dev>
AllowedIPs = 192.0.2.3/32
[Peer]
# Name = public-server1.example-vpn.tld
Endpoint = public-server1.example-vpn.tld:51820
PublicKey = <public key for public-server1.example-vpn.tld>
# routes traffic to itself and entire subnet of peers as bounce server
AllowedIPs = 192.0.2.1/24
PersistentKeepalive = 25
# Name
นี่เป็นเพียงความคิดเห็นมาตรฐานในรูปแบบ INI ที่ใช้เพื่อช่วยติดตามว่าส่วนการกำหนดค่าใดเป็นของโหนดใด WireGuard จะละเว้นโดยสิ้นเชิง และไม่มีผลกระทบต่อพฤติกรรมของ VPN
Endpoint
กำหนดที่อยู่ที่เข้าถึงได้แบบสาธารณะสำหรับเพียร์ระยะไกล สิ่งนี้ควรละไว้สำหรับเพียร์ที่อยู่เบื้องหลัง NAT หรือเพียร์ที่ไม่มีคู่ IP:PORT ที่เข้าถึงได้แบบสาธารณะที่เสถียร โดยทั่วไป จะต้องกำหนดสิ่งนี้บนเซิร์ฟเวอร์ตีกลับหลักเท่านั้น แต่ยังสามารถกำหนดบนโหนดสาธารณะอื่นๆ ที่มี IP ที่เสถียร เช่น public-server2
ในการกำหนดค่าตัวอย่างด้านล่าง
ตัวอย่าง
Endpoint = 123.124.125.126:51820
(รองรับ IPv6 ด้วย)Endpoint = public-server1.example-vpn.tld:51820
AllowedIPs
สิ่งนี้จะกำหนดช่วง IP ที่เพียร์จะกำหนดเส้นทางการรับส่งข้อมูล บนไคลเอนต์แบบธรรมดา โดยปกติจะเป็นที่อยู่เดียว (ที่อยู่ VPN ของไคลเอนต์แบบง่ายนั้นเอง) สำหรับเซิร์ฟเวอร์ตีกลับ นี่จะเป็นช่วงของ IP หรือซับเน็ตที่เซิร์ฟเวอร์รีเลย์สามารถกำหนดเส้นทางการรับส่งข้อมูลได้ สามารถระบุ IP และซับเน็ตหลายรายการได้โดยใช้เครื่องหมาย IPv4 หรือ IPv6 CIDR ที่คั่นด้วยเครื่องหมายจุลภาค (จากที่อยู่ /32 หรือ /128 เดียว จนถึง 0.0.0.0/0
และ ::/0
เพื่อระบุเส้นทางเริ่มต้นที่จะส่งทั้งหมด การรับส่งข้อมูลอินเทอร์เน็ตและ VPN ผ่านเพียร์นั้น) ตัวเลือกนี้อาจระบุได้หลายครั้ง
เมื่อตัดสินใจว่าจะกำหนดเส้นทางแพ็กเก็ตอย่างไร ระบบจะเลือกเส้นทางที่เฉพาะเจาะจงที่สุดก่อน และถอยกลับไปยังเส้นทางที่กว้างกว่า ดังนั้นสำหรับแพ็กเก็ตที่กำหนดไปที่ 192.0.2.3
ระบบจะค้นหาการโฆษณาแบบเพียร์ 192.0.2.3/32
โดยเฉพาะก่อน และจะกลับไปใช้การโฆษณาแบบเพียร์ 192.0.2.1/24
หรือช่วงที่ใหญ่กว่าเช่น 0.0.0.0/0
เป็น ทางเลือกสุดท้าย
ตัวอย่าง
peer เป็นไคลเอนต์ธรรมดาที่ยอมรับเฉพาะการรับส่งข้อมูลไปยัง/จากตัวมันเองเท่านั้น
AllowedIPs = 192.0.2.3/32
เพียร์เป็นเซิร์ฟเวอร์ส่งต่อที่สามารถตีกลับการรับส่งข้อมูล VPN ไปยังเพียร์อื่น ๆ ทั้งหมด
AllowedIPs = 192.0.2.1/24
peer คือเซิร์ฟเวอร์ส่งต่อที่ตีกลับการรับส่งข้อมูลอินเทอร์เน็ตและ VPN ทั้งหมด (เช่น พร็อกซี) รวมถึง IPv6
AllowedIPs = 0.0.0.0/0,::/0
เพียร์เป็นเซิร์ฟเวอร์รีเลย์ที่กำหนดเส้นทางไปยังตัวเองและมีเพียงเพียร์อื่นเท่านั้น
AllowedIPs = 192.0.2.3/32,192.0.2.4/32
peer คือเซิร์ฟเวอร์รีเลย์ที่กำหนดเส้นทางไปยังตัวเองและโหนดทั้งหมดบน LAN ภายในเครื่อง
AllowedIPs = 192.0.2.3/32,192.168.1.1/24
PublicKey
นี่คือคีย์สาธารณะสำหรับโหนดระยะไกล ซึ่งสามารถแชร์กับเพียร์ทั้งหมดได้ โหนดทั้งหมดต้องมีชุดคีย์สาธารณะ ไม่ว่าจะเป็นเซิร์ฟเวอร์ตีกลับสาธารณะที่ถ่ายทอดการรับส่งข้อมูล หรือไคลเอนต์ธรรมดาที่เข้าร่วม VPN
คีย์นี้สามารถสร้างขึ้นได้ด้วย wg pubkey < example.key > example.key.pub
(ดูด้านบนสำหรับวิธีสร้างคีย์ส่วนตัว example.key
)
ตัวอย่าง
PublicKey = somePublicKeyAbcdAbcdAbcdAbcd=
PersistentKeepalive
หากการเชื่อมต่อเป็นไปจากเพียร์ NAT-ed ไปยังเพียร์สาธารณะ โหนดที่อยู่เบื้องหลัง NAT จะต้องส่ง Ping ขาออกเป็นประจำเพื่อรักษาการเชื่อมต่อแบบสองทิศทางให้คงอยู่ในตารางการเชื่อมต่อของเราเตอร์ NAT
ตัวอย่าง
โหนดสาธารณะในพื้นที่ไปยังโหนดสาธารณะระยะไกล
ค่านี้ไม่ควรถูกกำหนดไว้เนื่องจากไม่จำเป็นต้องส่ง Ping อย่างต่อเนื่อง
โหนดสาธารณะในพื้นที่ไปยังโหนด NAT-ed ระยะไกล
ค่านี้ไม่ควรถูกกำหนดไว้ เนื่องจากเป็นความรับผิดชอบของลูกค้าในการรักษาการเชื่อมต่อให้คงอยู่ เนื่องจากเซิร์ฟเวอร์ไม่สามารถเปิดการเชื่อมต่อที่ไม่ทำงานไปยังไคลเอนต์ได้อีกครั้งหากหมดเวลา
โหนด NAT-ed ท้องถิ่นไปยังโหนดสาธารณะระยะไกล
PersistentKeepalive = 25
สิ่งนี้จะส่ง Ping ไปทุก ๆ 25 วินาทีโดยทำให้การเชื่อมต่อเปิดอยู่ในตารางการเชื่อมต่อของเราเตอร์ NAT ในเครื่อง
ตัวอย่างในเอกสารเหล่านี้ใช้ IPv4 เป็นหลัก แต่ Wireguard สนับสนุนสัญกรณ์ IPv6 CIDR และที่อยู่ทุกที่ที่รองรับ IPv4 เพียงเพิ่มพวกเขาเช่นเดียวกับที่คุณต้องการช่วงย่อยหรือที่อยู่อื่น ๆ
ตัวอย่าง
[Interface]
Address = 192.0.2.3/24, 2001:DB8::/64
[Peer]
...
AllowedIPs = 0.0.0.0/0, ::/0
หากคุณต้องการส่งต่อการรับส่งข้อมูลทางอินเทอร์เน็ต ทั้งหมด ผ่าน VPN และไม่เพียง แต่ใช้เป็นเครือข่ายย่อยเซิร์ฟเวอร์ไปยังเซิร์ฟเวอร์คุณสามารถเพิ่ม 0.0.0.0/0, ::/0
ในคำจำกัดความ AllowedIPs
ของเพียร์ที่คุณต้องการท่อ การจราจรของคุณผ่าน
ตรวจสอบให้แน่ใจว่าได้ระบุ IPv6 catchall แม้ว่าจะส่งต่อการรับส่งข้อมูล IPv4 เท่านั้นเพื่อหลีกเลี่ยงการรั่วไหลของแพ็กเก็ต IPv6 ที่รั่วไหลออกไปด้านนอก VPN ดู:
https://www.reddit.com/r/wireguard/comments/b0m5g2/ipv6_leaks_psa_for_anyone_here_using_wireguard_to/
ตัวอย่าง
[Interface]
# Name = phone.example-vpn.dev
Address = 192.0.2.3/32
PrivateKey = <private key for phone.example-vpn.dev>
[Peer]
# Name = public-server1.example-vpn.dev
PublicKey = <public key for public-server1.example-vpn.dev>
Endpoint = public-server1.example-vpn.dev:51820
AllowedIPs = 0.0.0.0/0, ::/0
Wireguard บางครั้งสามารถเชื่อมต่อระหว่างไคลเอนต์สองตัวที่อยู่เบื้องหลัง NATS โดยไม่จำเป็นต้องใช้เซิร์ฟเวอร์รีเลย์สาธารณะ แต่ในกรณีส่วนใหญ่เป็นไปไม่ได้ การเชื่อมต่อ Nat-to-Nat เป็นไปได้เฉพาะเมื่อโฮสต์อย่างน้อยหนึ่งโฮสต์มีที่อยู่ IP ที่มีเสถียรภาพและเข้าถึงได้สาธารณะ: คู่พอร์ตที่สามารถใช้งานได้ล่วงหน้าไม่ว่า พอร์ต NAT ที่ไม่ได้สุ่มเปิดโดยแพ็คเก็ตขาออกทุกอย่างทำงานได้ตราบใดที่เพื่อนทุกคนสามารถสื่อสารได้ล่วงหน้าและจะไม่เปลี่ยนแปลงเมื่อการเชื่อมต่อเริ่มต้นขึ้น
พอร์ตและที่อยู่ที่รู้จักจะต้องได้รับการกำหนดค่าล่วงหน้าเนื่องจาก Wireguard ไม่มีเลเยอร์การส่งสัญญาณหรือเซิร์ฟเวอร์ Stun สาธารณะที่สามารถใช้ในการค้นหาโฮสต์อื่น ๆ แบบไดนามิก WEBRTC เป็นตัวอย่างของโปรโตคอลที่สามารถกำหนดค่าการเชื่อมต่อระหว่างสอง NATs ได้แบบไดนามิก แต่ทำสิ่งนี้โดยใช้เซิร์ฟเวอร์การส่งสัญญาณนอกแบนเพื่อตรวจจับ IP: พอร์ตคอมโบของแต่ละโฮสต์ Wireguard ไม่มีสิ่งนี้ดังนั้นจึงใช้งานได้กับ Endpoint
PersistentKeepalive
Hardcoded + ListenPort
เรียนรู้เพิ่มเติมจากคัมภีร์ไบเบิลของ Tailscale ใน Nat Traversal: https://tailscale.com/blog/how-nat-traversal-works/
Endpoint
ที่สามารถเข้าถึงได้โดยตรงและเข้าถึงได้โดยตรง หากทั้งคู่อยู่เบื้องหลัง NATS ที่ไม่มีที่อยู่ IP ที่เสถียรคุณจะต้องใช้ DNS แบบไดนามิกหรือโซลูชันอื่นเพื่อให้มีโดเมน/IP ที่มีเสถียรภาพListenPort
และเราเตอร์ NAT จะต้องไม่ทำการสุ่มพอร์ตแหล่งกำเนิด UDP มิฉะนั้นแพ็คเก็ตส่งคืนจะถูกส่งไปยัง Hardcoded ListenPort
และทิ้งโดยเราเตอร์แทนที่จะใช้พอร์ตสุ่มที่กำหนดโดย NAT บนแพ็คเก็ตขาออกPersistentKeepalive
กระบวนการส่งแพ็คเก็ตเริ่มต้นที่ได้รับการปฏิเสธจากนั้นใช้ความจริงที่ว่าเราเตอร์ได้สร้างกฎการส่งต่อเพื่อยอมรับคำตอบเรียกว่า "การเจาะรู UDP"
เมื่อคุณส่งแพ็กเก็ต UDP ออกเราเตอร์ (โดยปกติ) จะสร้างกฎชั่วคราวการแมปที่อยู่ต้นทางและพอร์ตของคุณไปยังที่อยู่ปลายทางและพอร์ตและในทางกลับกัน แพ็คเก็ต UDP ที่กลับมาจากที่อยู่ปลายทางและพอร์ต (และไม่มีอื่น) จะถูกส่งผ่านไปยังที่อยู่ต้นฉบับและพอร์ตต้นฉบับ (และไม่มีอื่น ๆ ) นี่คือวิธีที่แอปพลิเคชัน UDP ส่วนใหญ่ทำงานอยู่เบื้องหลัง NATS (เช่น BitTorrent, Skype ฯลฯ ) กฎนี้จะหมดเวลาหลังจากไม่มีการใช้งานไม่กี่นาทีดังนั้นลูกค้าที่อยู่เบื้องหลัง NAT จะต้องส่งแพ็คเก็ตขาออกปกติเพื่อให้เปิด (ดู PersistentKeepalive
)
การทำให้สิ่งนี้ทำงานได้เมื่อจุดสิ้นสุดทั้งสองอยู่เบื้องหลัง NATS หรือไฟร์วอลล์ต้องการให้ทั้งสองจุดสิ้นสุดส่งแพ็คเก็ตไปยังแต่ละอื่น ๆ ในเวลาเดียวกัน ซึ่งหมายความว่าทั้งสองฝ่ายจำเป็นต้องรู้ที่อยู่ IP สาธารณะของแต่ละคนและหมายเลขพอร์ตล่วงหน้าในกรณีของ Wireguard ซึ่งสามารถทำได้โดยพอร์ตที่กำหนดไว้ล่วงหน้าที่กำหนดไว้ล่วงหน้าสำหรับทั้งสองฝ่ายใน wg0.conf
ในปี 2562 วิธีการชกหลุมเก่าจำนวนมากที่ใช้ซึ่งใช้ในการทำงานนั้นไม่มีประสิทธิภาพอีกต่อไป ตัวอย่างหนึ่งคือวิธีการใหม่ที่บุกเบิกโดย PWNAT ที่ปลอมเวลา ICMP เกินกว่าการตอบสนองจากนอก NAT เพื่อให้ได้แพ็คเก็ตกลับไปที่เพื่อนร่วมทาง พอร์ต UDP แบบฮาร์ดโค้ดและ IPS สาธารณะสำหรับทั้งสองด้านของการเชื่อมต่อ NAT-to-Nat (ตามที่อธิบายไว้ข้างต้น) ยังคงใช้งานได้กับเครือข่ายเพียงเล็กน้อย โดยทั่วไปยิ่งเครือข่าย "Enterprisey" มากเท่าไหร่ก็ยิ่งมีโอกาสน้อยที่คุณจะสามารถเจาะพอร์ต UDP สาธารณะ Punch (Wi-Fi สาธารณะเชิงพาณิชย์และข้อมูลเซลล์ NATs มักจะไม่ทำงาน)
การเชื่อมต่อ Nat-to-Nat เป็นไปไม่ได้หากจุดสิ้นสุดทั้งหมดอยู่เบื้องหลัง NAT ของ NAT ด้วยการสุ่มพอร์ต UDP ที่เข้มงวด (เช่นเครือข่ายข้อมูลเซลลูลาร์ส่วนใหญ่) เนื่องจากทั้งสองฝ่ายไม่สามารถใช้ฮาร์ดคอด ListenPort
และรับประกันได้ว่า NAT ของพวกเขาจะยอมรับการรับส่งข้อมูลบนพอร์ตนั้นหลังจาก ping ขาออกคุณจึงไม่สามารถประสานพอร์ตสำหรับรูหลุมเริ่มต้นระหว่างเพื่อนและการเชื่อมต่อจะล้มเหลว ด้วยเหตุนี้คุณจึงไม่สามารถเชื่อมต่อโทรศัพท์กับโทรศัพท์ได้ในเครือข่าย LTE/3G แต่คุณอาจสามารถทำการโทรศัพท์ไปยังสำนักงานหรือโทรศัพท์ไปที่บ้านได้ซึ่งสำนักงานหรือที่บ้านมี IP สาธารณะที่มีเสถียรภาพ 'ไม่สุ่มพอร์ตแหล่งที่มา
การเชื่อมต่อ Nat-to-nat จากด้านหลัง NATS ด้วยการสุ่มแบบพอร์ตแหล่งที่เข้มงวดเป็นไปได้คุณเพียงแค่ต้องมีเซิร์ฟเวอร์การส่งสัญญาณเพื่อบอกแต่ละด้าน IP ของอีกฝ่าย: Tuple พอร์ต นี่คือการใช้งานบางอย่างที่บรรลุเป้าหมายนี้ด้วย Wireguard:
ผู้ใช้หลายคนรายงานว่าต้องรีสตาร์ท Wireguard เมื่อใดก็ตามที่มีการเปลี่ยนแปลง IP แบบไดนามิกเนื่องจากจะแก้ไขชื่อโฮสต์ในการเริ่มต้นเท่านั้น ในการบังคับให้ Wireguard ทำการแก้ไข Endpoint
HostNames DNS DNS DNS ซ้ำบ่อยขึ้นคุณอาจต้องการใช้เบ็ด PostUp
เพื่อรีสตาร์ท Wireguard ทุกสองสามนาทีหรือชั่วโมง
คุณสามารถดูได้ว่าการตั้งค่าการเจาะรูเป็นไปได้หรือไม่โดยใช้ NetCat บนไคลเอนต์และเซิร์ฟเวอร์เพื่อดูว่าพอร์ตและคำสั่งการเชื่อมต่อใดทำงานเพื่อเปิดการเชื่อมต่อแบบสองทิศทาง: เรียกใช้ nc -v -u -p 51820 <address of peer2> 51820
( บน peer1) และ nc -v -u -l 0.0.0.0 51820
(บน peer2) จากนั้นพิมพ์ทั้งสองหน้าต่างเพื่อดูว่าคุณจะได้รับปริมาณการใช้งานแบบสองทิศทางหรือไม่ หากไม่ได้ผลไม่ว่าเพียร์จะส่งแพ็กเก็ตเริ่มต้นใดก็ตาม Wireguard จะไม่สามารถทำงานระหว่างเพื่อนได้โดยไม่ต้องใช้เซิร์ฟเวอร์รีเลย์สาธารณะ
การเชื่อมต่อ Nat-to-Nat มักจะไม่เสถียรมากขึ้นและมีข้อ จำกัด อื่น ๆ ซึ่งเป็นเหตุผลว่าทำไมการมีเซิร์ฟเวอร์รีเลย์สาธารณะทางเลือกยังคงแนะนำ
ตัวอย่าง
Peer1:
[Interface]
...
ListenPort 12000
[Peer]
...
Endpoint = peer2.example-vpn.dev:12000
PersistentKeepalive = 25
peer2:
[Interface]
...
ListenPort 12000
[Peer]
...
Endpoint = peer1.example-vpn.dev:12000
PersistentKeepalive = 25
หมายเหตุ: ส่วนนี้เป็นเรื่องเกี่ยวกับ IPS แบบไดนามิกภายในซับเน็ต VPN ไม่ใช่ที่อยู่ Endpoint
สาธารณะแบบไดนามิก
การจัดสรรแบบไดนามิกของเพียร์ IPS (แทนที่จะมีการพัฒนาโดยเฉพาะ) เท่านั้น
นอกจากนี้คุณยังสามารถสร้างระบบการจัดสรรแบบไดนามิกด้วยตัวเองโดยการอ่านค่า IP จากไฟล์ที่รันไทม์โดยใช้ PostUp
(ดูด้านล่าง)
ตัวอย่าง
[Interface]
...
PostUp = wg set %i allowed-ips /etc/wireguard/wg0.key <(some command)
https://git.zx2c4.com/wireguard-go/about/
การใช้งาน Wireguard ของ Userland ที่สอดคล้องกันซึ่งเขียนขึ้นใน GO
https://git.zx2c4.com/wireguard-rs/about/
การใช้งานผู้ใช้ที่ไม่ปลอดภัยและไม่ปลอดภัยของ Wireguard ที่เขียนด้วย Rust (ไม่พร้อมสำหรับสาธารณะ)
https://git.zx2c4.com/wireguard-hs/about/
การใช้งานผู้ใช้ที่ไม่ปลอดภัยและไม่ปลอดภัยของ Wireguard ที่เขียนใน Haskell (ไม่พร้อมสำหรับสาธารณะ)
https://github.com/cloudflare/boringtun
การใช้งาน Wireguard อิสระที่ไม่สอดคล้องและเป็นอิสระเขียนใน Rust (แยกจากกันซึ่งเขียนโดย CloudFlare) ดู https://blog.cloudflare.com/boringtun-userspace-wireguard-rust/
แอพ Wireguard เฉพาะแพลตฟอร์ม
https://git.zx2c4.com/wireguard-ios/about/
https://git.zx2c4.com/wireguard-android/about/
https://git.zx2c4.com/wireguard-windows/about/
การใช้งาน userspace ทั้งหมดช้ากว่ารุ่น C ดั้งเดิมที่ทำงานในเคอร์เนล-ที่ดิน แต่ให้ประโยชน์อื่น ๆ โดยการทำงานใน Userland (เช่นคอนเทนเนอร์ที่ง่ายขึ้นความเข้ากันได้ ฯลฯ )
นี่คือเครื่องมือ GUI และ CLI ที่ห่อหุ้ม Wireguard เพื่อช่วยในการกำหนดค่าการปรับใช้การจัดการคีย์และการเชื่อมต่อ
เครดิตสำหรับทางลัดเหล่านี้ไปที่: https://www.ericlight.com/new-things-i-didnt-know-about-wireguard.html
Wireguard จะเพิกเฉยต่อเพื่อนที่คีย์สาธารณะตรงกับรหัสส่วนตัวของอินเทอร์เฟซ ดังนั้นคุณสามารถแจกจ่ายรายชื่อคนรอบเดียวได้ทุกที่และกำหนด [Interface]
แยกต่างหากในแต่ละเซิร์ฟเวอร์
ดู: https://lists.zx2c4.com/pipermail/wireguard/2018-december/003703.html
คุณสามารถรวมสิ่งนี้เข้ากับ wg addconf
เช่นนี้:
เพียร์แต่ละตัวมีไฟล์ /etc/wireguard/wg0.conf
ของตัวเองซึ่งมีส่วน [Interface]
เท่านั้น
เพียร์แต่ละคนยังมีไฟล์ /etc/wireguard/peers.conf
ที่ใช้ร่วมกันซึ่งมีเพื่อนทั้งหมด
ไฟล์ wg0.conf
ยังมีตะขอ PostUp
: PostUp = wg addconf /etc/wireguard/peers.conf
มันขึ้นอยู่กับคุณที่จะตัดสินใจว่าคุณต้องการแบ่งปัน peers.conf
ไม่ว่าจะผ่านแพลตฟอร์มการประสานที่เหมาะสมมีบางสิ่งที่มากกว่าคนเดินเท้าเช่น Dropbox หรือบางสิ่งบางอย่างที่ชอบ Ceph ฉันไม่รู้ แต่มันก็ค่อนข้างดีที่คุณสามารถเหวี่ยงส่วนเพียร์ไปรอบ ๆ ได้โดยไม่ต้องกังวลว่ามันจะเหมือนกับอินเทอร์เฟซหรือไม่
คุณสามารถตั้งค่าค่ากำหนดค่าจากคำสั่งโดยพลการหรือโดยการอ่านค่าจากไฟล์สิ่งนี้ทำให้การจัดการคีย์และการปรับใช้ง่ายขึ้นมากเพราะคุณสามารถอ่านในคีย์ที่รันไทม์จากบริการบุคคลที่สามเช่น Kubernetes Secrets หรือ AWS KMS
ดู: https://lists.zx2c4.com/pipermail/wireguard/2018-december/003702.html
ตัวอย่าง
คุณสามารถอ่านในไฟล์เป็น PrivateKey
โดยทำอะไรบางอย่างเช่น:
PostUp = wg set %i private-key /etc/wireguard/wg0.key <(some command)
Wireguard สามารถทำงานได้ใน Docker ด้วยระดับความสะดวกที่แตกต่างกัน ในกรณีที่ง่ายที่สุด --privileged
และ --cap-add=all
สามารถเพิ่มลงในคำสั่ง Docker เพื่อเปิดใช้งานการโหลดของโมดูลเคอร์เนล
การตั้งค่าอาจมีความซับซ้อนและขึ้นอยู่กับสิ่งที่คุณพยายามจะบรรลุ คุณสามารถให้ Wireguard ทำงานในคอนเทนเนอร์และเปิดเผยอินเทอร์เฟซเครือข่ายไปยังโฮสต์หรือคุณสามารถให้ Wireguard ทำงานบนโฮสต์ที่เปิดเผยอินเทอร์เฟซไปยังคอนเทนเนอร์ที่เฉพาะเจาะจง
ดูตัวอย่างด้านล่างสำหรับตัวอย่างของคอนเทนเนอร์ Docker vpn_test
การกำหนดเส้นทางการรับส่งข้อมูลทั้งหมดผ่านเซิร์ฟเวอร์รีเลย์ Wireguard
version : ' 3 '
services :
wireguard :
image : linuxserver/wireguard
ports :
- 51820:51820/udp
cap_add :
- NET_ADMIN
- SYS_MODULE
volumes :
- /lib/modules:/lib/modules
- ./wg0.conf:/config/wg0.conf:ro
wg0.conf
:
[Interface]
# Name = relay1.wg.example.com
Address = 192.0.2.1/24
ListenPort = 51820
PrivateKey = oJpRt2Oq27vIB5/ UVb7BRqCwad2YMReQgH5tlxz8YmI =
DNS = 1.1.1.1,8.8.8.8
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT ; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT ; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
# Name = peer1.wg.example.com
PublicKey = I+hXRAJOG/UE2IQvIHsou2zTgkUyPve2pzvHTnd/ 2Gg =
AllowedIPs = 192.0.2.2/32
ในตัวอย่างนี้การรับส่งข้อมูล ทั้งหมด จากภายในคอนเทนเนอร์ speedtest
จะผ่าน Wireguard VPN หากต้องการกำหนดเส้นทางการรับส่งข้อมูลเพียงเล็กน้อยให้แทนที่ 0.0.0.0/0
ใน wg0.conf
ด้านล่างด้วยช่วงย่อยที่คุณต้องการกำหนดเส้นทางผ่าน VPN
docker-compose.yml
:
version : ' 3 '
services :
wireguard :
image : linuxserver/wireguard
cap_add :
- NET_ADMIN
- SYS_MODULE
volumes :
- /lib/modules:/lib/modules
- ./wg0.conf:/config/wg0.conf:ro
vpn_test :
image : curlimages/curl
entrypoint : curl -s http://whatismyip.akamai.com/
network_mode : ' service:wireguard '
wg0.conf
:
[Interface]
# Name = peer1.wg.example.com
Address = 192.0.2.2/32
PrivateKey = YCW76edD4W7nZrPbWZxPZhcs32CsBLIi1sEhsV/ sgk8 =
DNS = 1.1.1.1,8.8.8.8
[Peer]
# Name = relay1.wg.example.com
Endpoint = relay1.wg.example.com:51820
PublicKey = zJNKewtL3gcHdG62V3GaBkErFtapJWsAx+ 2um0c0B1s =
AllowedIPs = 192.0.2.1/24,0.0.0.0/0
PersistentKeepalive = 21
สำหรับรายละเอียดเพิ่มเติมโปรดดูการอ่านเพิ่มเติม: ส่วน Docker ด้านล่าง
สำหรับคำแนะนำโดยละเอียดเพิ่มเติมโปรดดูคู่มือ QuickStart และ API อ้างอิงด้านบน นอกจากนี้คุณยังสามารถดาวน์โหลดการตั้งค่าตัวอย่างที่สมบูรณ์ได้ที่นี่: https://github.com/pirate/wireguard-example
แนะนำการเปลี่ยนแปลง: https://github.com/pirate/wireguard-docs/issues