מחולל קונפיגורציית WireGuard

מתארים את השרת ואת מי שמתחבר אליו, ומקבלים את כל קובצי התצורה: ‏wg0.conf לשרת, קובץ לכל מחשב, טלפון או שרת שמתחבר, הפקודות להפעלה וחוקי חומת האש. כברירת מחדל המפתחות נוצרים עם wg במחשב שלכם; אם תבחרו, הדפדפן הזה יוצר אותם. העמוד הזה לא טוען analytics, ושום דבר לא יוצא ממנו.

השרת
שם ה-host הציבורי או כתובת ה-IP שה-peers מתחברים אליה, למשל vpn.example.com.
‏WireGuard מאזין ב-UDP. ‏51820 הוא הפורט המקובל.
טווח IPv4 פרטי שמשמש רק את המנהרה. השרת מקבל את הכתובת הראשונה בו, וכל peer את הכתובת הבאה.
הממשק שדרכו תעבורה מועברת יוצאת מהשרת, בדרך כלל eth0 או ens3 (ראו ip route show default). משמש ל-full tunnel ולרשתות שמאחורי השרת.
סקריפט חומת האש משאיר אותו פתוח, כך שהפעלת ufw לא נועלת אתכם בחוץ.
Peers
השם של הקובץ ושל הממשק במכשיר, למשל laptop: עד 15 אותיות לטיניות, ספרות או _ = + . -
תעבורה
ב-split tunnel: טווחים שה-peers מגיעים אליהם דרך השרת, כמו ה-LAN שלו או VPC בענן, מופרדים בפסיקים. למשל 192.168.10.0/24.
כתובות IP מופרדות בפסיקים. שימושי ב-full tunnel, כדי ששאילתות DNS יעברו גם הן במנהרה.
ה-peers שולחים חבילה קטנה בתדירות הזו, כדי שנתב NAT או חומת אש לפניהם ישאירו את המנהרה פתוחה. ‏25 הוא הערך המקובל; ‏0 מכבה.
מפתח סימטרי נוסף שכל peer חולק עם השרת, מעבר לזוג המפתחות: שכבת הגנה נוספת, ש-wg(8) מתאר כעמידות מפני מחשבים קוונטיים (post-quantum).

או יצירת המפתחות בדפדפן הזה (לא חובה)

למקרה ש-wg לא זמין, או כדי לסרוק קוד QR מהמסך הזה. הדפדפן יוצר את המפתחות במכשיר הזה: הם לא נשלחים לשום מקום, לא נשמרים, לא נכנסים לקישור ולא נמדדים.

מה הכלי עושה

הכלי כותב התקנת WireGuard שלמה לשרת אחד ולמכשירים שמתחברים אליו: ‏wg0.conf לשרת עם בלוק [Peer] לכל מכשיר, קובץ משלו לכל מכשיר שבו השרת הוא ה-peer, הפקודות להפעלת המנהרה בשרת, סקריפט חומת אש של ufw, וקוד QR לטלפונים כשהמפתחות נוצרים כאן. הכתובות מגיעות מרשת מנהרה אחת, שנבדקת מול הרשתות ש-Docker יוצר.

איך זה עובד

  1. כל קובץ נכתב באותו מנוע של שאר כלי ה-Linux שלנו (@anaroq/linux). שמות, כתובות, טווחים והממשק נבדקים לפי צורתם, כך ששדה לא יכול להוסיף שורה משלו, ושני peers לעולם לא מקבלים את אותן כתובות.
  2. כברירת מחדל הקבצים מכילים placeholders, וסקריפט קצר יוצר כל מפתח עם wg genkey, ‏wg pubkey ו-wg genpsk במחשב שלכם וכותב אותו פנימה. הבדיקות שלנו מריצות את הסקריפט הזה ומעלות את השרת וה-peers עם wg-quick בקונטיינרים, ואז בודקות את ה-handshake, את המנהרה בשני הכיוונים, וב-full tunnel גם NAT ל-host מחוץ למנהרה.
  3. אם יוצרים את המפתחות כאן, ‏WebCrypto X25519 של הדפדפן יוצר אותם (או, בדפדפן שאין בו, ספריית tweetnacl שנארזה עם העמוד); הבדיקות שלנו מוודאות שהמפתח הציבורי שנגזר מכל מפתח פרטי הוא זה ש-wg pubkey מדפיס, על מפתחות ידועים ועל מפתחות חדשים.
  4. העמוד הזה לא טוען analytics, מדיניות האבטחה שלו מאפשרת לו להתחבר רק לאתר הזה, ושום דבר לא נשמר בקישור או באחסון של הדפדפן.

מה כל אפשרות עושה

Address ו-AllowedIPs
כל מכשיר מקבל כתובת אחת ברשת המנהרה. בשרת, ה-AllowedIPs של peer הוא הכתובת האחת הזו: תעבורה אליה הולכת ל-peer הזה, ותעבורה ממנו מתקבלת רק עם המקור הזה. ב-peer, ‏AllowedIPs הוא מה שעובר במנהרה.
Full ו-split tunnel
‏full tunnel שולח את 0.0.0.0/0 ואת ‎::/0 דרך השרת, כך שכל התעבורה יוצאת מהכתובת של השרת. ‏split tunnel שולח רק את רשת המנהרה ואת הרשתות שציינתם.
PostUp ו-PostDown ‏(NAT)
כשהשרת מעביר תעבורה, ‏wg-quick מריץ את חוקי ה-iptables האלה כשהמנהרה עולה ויורדת: העברה אל המנהרה וממנה מתקבלת, ורשת המנהרה עוברת masquerade דרך ממשק השרת.
PersistentKeepalive
חבילה מה-peer כל כמה שניות שומרת פתוח את מיפוי ה-NAT של הנתב שלו, כך שהשרת יכול להגיע ל-peer שהיה שקט.
PresharedKey
מפתח סימטרי שמשתלב ב-handshake, ייחודי לכל זוג של שרת ו-peer. הוא מוסיף הגנה מעל זוג המפתחות ולא מחליף אותו.

דוגמה

שרת ב-vpn.example.com ושני peers, מחשב נייד וטלפון, ב-split tunnel על 10.8.0.0/24, עם מפתחות שנוצרים ב-wg:

‏wg0.conf של השרת
wg0.conf
# WireGuard interface wg0. Contains a private key: keep it mode 0600.
# Generated by @anaroq/linux 1.0.0 (ANAROQ). Start with: sudo systemctl enable --now wg-quick@wg0
[Interface]
PrivateKey = @SERVER_PRIVATE_KEY@
Address = 10.8.0.1/24
ListenPort = 51820

# laptop
[Peer]
PublicKey = @PEER_1_PUBLIC_KEY@
PresharedKey = @PEER_1_PRESHARED_KEY@
AllowedIPs = 10.8.0.2/32

# phone
[Peer]
PublicKey = @PEER_2_PUBLIC_KEY@
PresharedKey = @PEER_2_PRESHARED_KEY@
AllowedIPs = 10.8.0.3/32
‏laptop.conf של המחשב הנייד
laptop.conf
# WireGuard interface laptop. Contains a private key: keep it mode 0600.
# Generated by @anaroq/linux 1.0.0 (ANAROQ). Start with: sudo systemctl enable --now wg-quick@laptop
[Interface]
PrivateKey = @PEER_1_PRIVATE_KEY@
Address = 10.8.0.2/32

# server vpn.example.com
[Peer]
PublicKey = @SERVER_PUBLIC_KEY@
PresharedKey = @PEER_1_PRESHARED_KEY@
AllowedIPs = 10.8.0.0/24
Endpoint = vpn.example.com:51820
PersistentKeepalive = 25
והסקריפט שיוצר את המפתחות במחשב שלכם:
make-wireguard-keys.sh
#!/usr/bin/env bash
# Makes the WireGuard keys with wg on this computer and writes them into the config
# files in this directory, in place of their @…_KEY@ placeholders. Generated by ANAROQ.
# Usage: bash make-wireguard-keys.sh   (needs wireguard-tools: wg genkey, wg pubkey, wg genpsk)
set -euo pipefail
umask 077

command -v wg >/dev/null 2>&1 || { echo 'wg not found: install wireguard-tools first.' >&2; exit 1; }
for f in wg0.conf laptop.conf phone.conf; do
  [ -f "$f" ] || { echo "$f is not in this directory." >&2; exit 1; }
done
grep -q '@SERVER_PRIVATE_KEY@' wg0.conf || { echo 'The keys are already filled in.' >&2; exit 1; }

# fill FILE PLACEHOLDER KEY: base64 keys have no | or &, so sed takes them as they are.
fill() {
  local tmp
  tmp=$(mktemp)
  sed "s|$2|$3|g" "$1" > "$tmp"
  cat "$tmp" > "$1"
  rm -f "$tmp"
}

server_key=$(wg genkey)
server_pub=$(printf '%s\n' "$server_key" | wg pubkey)
fill wg0.conf @SERVER_PRIVATE_KEY@ "$server_key"

# Peer 1: laptop
key=$(wg genkey)
pub=$(printf '%s\n' "$key" | wg pubkey)
fill laptop.conf @PEER_1_PRIVATE_KEY@ "$key"
fill laptop.conf @SERVER_PUBLIC_KEY@ "$server_pub"
fill wg0.conf @PEER_1_PUBLIC_KEY@ "$pub"
psk=$(wg genpsk)
fill laptop.conf @PEER_1_PRESHARED_KEY@ "$psk"
fill wg0.conf @PEER_1_PRESHARED_KEY@ "$psk"

# Peer 2: phone
key=$(wg genkey)
pub=$(printf '%s\n' "$key" | wg pubkey)
fill phone.conf @PEER_2_PRIVATE_KEY@ "$key"
fill phone.conf @SERVER_PUBLIC_KEY@ "$server_pub"
fill wg0.conf @PEER_2_PUBLIC_KEY@ "$pub"
psk=$(wg genpsk)
fill phone.conf @PEER_2_PRESHARED_KEY@ "$psk"
fill wg0.conf @PEER_2_PRESHARED_KEY@ "$psk"

chmod 600 wg0.conf laptop.conf phone.conf
unset server_key key psk
echo 'Done: wg0.conf, laptop.conf, phone.conf now hold their keys. Keep them private (mode 600).'

מגבלות

  • שרת אחד, כתובות IPv4 במנהרה, ו-peers שמתחברים רק לשרת: אין mesh בין אתרים או בין peers, וזה לא VPN מנוהל (Tailscale, ‏NetBird וכלים דומים מנהלים בשבילכם מפתחות ו-peers).
  • ‏full tunnel מנתב גם IPv6 למנהרה (‎::/0) ולא נותן ל-peers כתובת IPv6, כך שתעבורת IPv6 נעצרת במקום לדלוף מחוץ למנהרה. ב-peer מסוג Linux שהליבה שלו רצה בלי IPv6, מסירים את ‎::/0 מהקובץ שלו.
  • הצעדים בשרת מיועדים ל-Debian או Ubuntu עם ufw ו-iptables; מערכות אחרות צריכות פקודות משלהן.
  • הכלי לא יכול לבדוק שהשרת זמין, שפורט ה-UDP פתוח בחומת האש של ספק הענן, או שהכתובת נכונה.
  • מפתחות שנוצרים בדפדפן בטוחים רק כמו המכשיר והדפדפן; הסקריפט של wg הוא ברירת המחדל הבטוחה יותר.

מתודולוגיה: איך מחושבים המספרים

מקורות

  1. WireGuard: Quick Start
  2. wg(8) manual page
  3. wg-quick(8) manual page
  4. RFC 7748: Elliptic Curves for Security (X25519)
  5. MDN: SubtleCrypto.generateKey() (X25519)
  6. Docker: default address pools (daemon.json)
  7. Ubuntu manual: ufw(8)

עודכן

הצעד הבא

מחולל SSH config ועוזר מפתחות

כלי ציבורי חינמי של אנרוק, חברה שבונה תשתיות מחשוב. מה אנרוק בונה