WireGuard Server Manual (Orange Pi / Armbian)

From wiki.baghirzade.pro
Jump to navigation Jump to search

📘 Описание

Этот документ описывает пошаговую установку и настройку WireGuard VPN на Orange Pi (или другом Debian/Armbian сервере), включая:

  • ручную установку и устранение ошибок DNS;
  • корректную настройку NAT с интерфейсом end0;
  • скрипты для добавления, просмотра и удаления клиентов (с QR-кодом);
  • защиту от ошибки A peer is missing a public key.

⚙️ 1. Подготовка системы

1.1 Проверяем интерфейс

ip a | grep -E 'eth|end'

На Orange Pi часто вместо eth0 используется интерфейс end0.

Запомни его имя — оно нужно для NAT-маскарадинга.

1.2 Настройка DNS (если apt не работает)

Если при apt update видишь:

System error resolving 'deb.debian.org:http' - getaddrinfo (16: Device or resource busy)

— тогда пересоздай /etc/resolv.conf:

sudo rm -f /etc/resolv.conf
echo "nameserver 1.1.1.1" | sudo tee /etc/resolv.conf

И запрети автоматическую перезапись (чтобы Armbian не ломал DNS):

sudo chattr +i /etc/resolv.conf

🛠️ 2. Установка WireGuard вручную

sudo apt update
sudo apt install wireguard qrencode -y

Проверим:

modprobe wireguard lsmod | grep wireguard

🔑 3. Создание ключей и конфига сервера

cd /etc/wireguard umask 077 wg genkey | tee privatekey | wg pubkey > publickey

Создаём /etc/wireguard/wg0.conf:

[Interface] Address = 10.10.100.1/24 SaveConfig = false PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o end0 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o end0 -j MASQUERADE ListenPort = 51820 PrivateKey = <твой_privatekey>

(Если у тебя не end0, замени на нужный интерфейс.) 🔥 4. Включаем IP-форвардинг

sudo sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf

🚀 5. Запуск сервера

sudo wg-quick up wg0 sudo systemctl enable wg-quick@wg0 sudo systemctl status wg-quick@wg0

Проверяем:

sudo wg show sudo iptables -t nat -L -n -v

📡 6. Port Forwarding

На роутере нужно открыть UDP-порт 51820 и пробросить его на IP Orange Pi (например, 10.10.0.2).

👤 7. Добавление клиента

Создай скрипт /root/wg-add-client.sh:

#!/usr/bin/env bash
# ==============================================
# WireGuard Add Client Script
# Author: Niji’s version, 2025
# ==============================================
set -euo pipefail
WG_CONF="/etc/wireguard/wg0.conf"
WG_IF="wg0"
WG_DIR="/etc/wireguard"

if [ "$(id -u)" -ne 0 ]; then echo "❌ Запустите от root"; exit 1; fi
if [ ! -f "$WG_CONF" ]; then echo "❌ Конфиг $WG_CONF не найден"; exit 1; fi

read -rp "Введите имя клиента: " CLIENT
CLIENT_IP=$(awk '/AllowedIPs/{print $3}' $WG_CONF | awk -F'[./]' '{print $4}' | sort -n | tail -1)
CLIENT_IP=$((CLIENT_IP+1))
[ "$CLIENT_IP" -lt 2 ] && CLIENT_IP=2

cd $WG_DIR
wg genkey | tee ${CLIENT}-privatekey | wg pubkey > ${CLIENT}-publickey
SERVER_PUB=$(awk '/PrivateKey/{getline; print $3}' /etc/wireguard/publickey 2>/dev/null || echo "")
SERVER_PUB=$(cat /etc/wireguard/publickey)
CLIENT_PRIV=$(cat ${CLIENT}-privatekey)
CLIENT_PUB=$(cat ${CLIENT}-publickey)
SERVER_IP=$(hostname -I | awk '{print $1}')

cat > ${CLIENT}.conf <<EOF
[Interface]
PrivateKey = ${CLIENT_PRIV}
Address = 10.10.100.${CLIENT_IP}/32
DNS = 1.1.1.1

[Peer]
PublicKey = ${SERVER_PUB}
Endpoint = ${SERVER_IP}:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
EOF

cat >> $WG_CONF <<EOF

# ### Client ${CLIENT}
[Peer]
PublicKey = ${CLIENT_PUB}
AllowedIPs = 10.10.100.${CLIENT_IP}/32
PersistentKeepalive = 25
EOF

wg-quick down $WG_IF >/dev/null 2>&1 || true
wg-quick up $WG_IF

qrencode -t ansiutf8 < ${CLIENT}.conf
echo "✅ Клиент ${CLIENT} создан успешно!"
echo "📄 Конфиг: ${WG_DIR}/${CLIENT}.conf"

Делаем исполняемым:

chmod +x /root/wg-add-client.sh

🗑️ 8. Удаление клиента (без риска “missing public key”) Создай /root/wg-del-client.sh:

#!/usr/bin/env bash
# ==============================================
# WireGuard client remover (safe + auto-clean)
# Author: Niji’s version, 2025
# ==============================================
set -euo pipefail
WG_CONF="/etc/wireguard/wg0.conf"
WG_IF="wg0"

if [ "$(id -u)" -ne 0 ]; then echo "❌ Запустите скрипт от root"; exit 1; fi
if [ ! -f "$WG_CONF" ]; then echo "❌ Файл $WG_CONF не найден!"; exit 1; fi

echo "📋 Найденные клиенты:"
echo
mapfile -t KEYS < <(grep -A1 "^\[Peer\]" "$WG_CONF" | grep PublicKey | awk '{print $3}')

if [ "${#KEYS[@]}" -eq 0 ]; then echo "❌ Клиенты не найдены."; exit 0; fi

for i in "${!KEYS[@]}"; do
  key="${KEYS[$i]}"
  name=$(awk -v k="$key" '/^# ### Client /{n=$4} /^PublicKey/ && $3==k{print n; exit}' "$WG_CONF")
  name="${name:-Unnamed-$((i+1))}"
  printf " %2d. %-15s %s\n" "$((i+1))" "$name" "$key"
done

echo
read -rp "Введите номер клиента для удаления: " NUM

if ! [[ "$NUM" =~ ^[0-9]+$ ]] || [ "$NUM" -lt 1 ] || [ "$NUM" -gt "${#KEYS[@]}" ]; then
  echo "❌ Неверный номер."; exit 1
fi

CLIENT_KEY="${KEYS[$((NUM-1))]}"
CLIENT_NAME=$(awk -v k="$CLIENT_KEY" '/^# ### Client /{n=$4} /^PublicKey/ && $3==k{print n; exit}' "$WG_CONF")
CLIENT_NAME="${CLIENT_NAME:-Unnamed-$NUM}"

echo
echo "⚠️  Подтвердите удаление клиента '$CLIENT_NAME' (PublicKey: $CLIENT_KEY)"
read -rp "Введите YES для подтверждения: " CONFIRM
if [ "$CONFIRM" != "YES" ]; then echo "❎ Отменено пользователем."; exit 0; fi

cp "$WG_CONF" "$WG_CONF.bak.$(date +%s)"
echo "🧩 Создан бэкап wg0.conf."

awk -v key="$CLIENT_KEY" '
  BEGIN{inside=0}
  /^\[Peer\]/ {if (inside==1) inside=0; block=""}
  {block = block $0 ORS}
  /^PublicKey/ && $3==key {inside=1}
  inside==0 && !/^$/ {print $0}
' "$WG_CONF" > "${WG_CONF}.tmp" && mv "${WG_CONF}.tmp" "$WG_CONF"

# 🧹 Удаляем пустые блоки
awk '
  BEGIN{inside=0}
  /^\[Peer\]/ {inside=1; peer=""}
  inside {peer=peer $0 ORS}
  /^$/ && inside {
    if (peer ~ /PublicKey/) print peer;
    peer=""; inside=0
  }
  !inside && !/^\[Peer\]/ && !/^$/ {print $0}
  END {
    if (inside && peer ~ /PublicKey/) print peer;
  }
' "$WG_CONF" > "${WG_CONF}.clean" && mv "${WG_CONF}.clean" "$WG_CONF"

wg-quick down "$WG_IF" >/dev/null 2>&1 || true
wg-quick up "$WG_IF"

echo "✅ Клиент '$CLIENT_NAME' удалён успешно!"
echo "📄 Бэкап сохранён: ${WG_CONF}.bak.*"
echo "🧹 Конфиг очищен автоматически (никаких 'missing public key' больше не будет)."

📊 9. Просмотр подключений Можно быстро проверить активных клиентов:

sudo wg show

Для красивого вывода можно добавить /root/wg-list-clients.sh (опционально):

#!/usr/bin/env bash
echo "📡 WireGuard peers:"
echo "----------------------------------------"
sudo wg show | awk '
/interface:/ {iface=$2}
/peer:/ {peer=$2}
/allowed ips:/ {ips=$3}
/endpoint:/ {endpoint=$2}
/transfer:/ {recv=$2 " " $3 ", " $5 " " $6}
/latest handshake:/ {print iface " | " peer " | " ips " | " endpoint " | " $3 " " $4 " " $5 " | " recv}
'

🧠 10. Полезные команды

Команда Назначение
sudo wg show Список клиентов и статистика
sudo wg-quick up wg0 Запуск WireGuard
sudo wg-quick down wg0 Остановка WireGuard
sudo systemctl restart wg-quick@wg0 Перезапуск
sudo wg syncconf wg0 <(wg-quick strip wg0) Применить изменения без перезапуска
sudo iptables -t nat -L -n -v Проверка NAT правил

✅ Итог Теперь твой WireGuard:

  • полностью автоматизирован;
  • работает на end0;
  • не ломается при удалении клиента;
  • создаёт и удаляет peers с бэкапами;
  • позволяет быстро добавить пользователя через QR-код.